home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume26 / cook-1.4 / part07 < prev    next >
Encoding:
Text File  |  1993-05-03  |  80.9 KB  |  3,309 lines

  1. Newsgroups: comp.sources.unix
  2. From: pmiller@bmr.gov.au (Peter Miller)
  3. Subject: v26i215: cook-1.4 - a file construction tool (like "make"), Part07/11
  4. Sender: unix-sources-moderator@efficacy.home.vix.com
  5. Approved: WhoAmI@efficacy.home.vix.com
  6.  
  7. Submitted-By: pmiller@bmr.gov.au (Peter Miller)
  8. Posting-Number: Volume 26, Issue 215
  9. Archive-Name: cook-1.4/part07
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 7 (of 11)."
  18. # Contents:  Makefile common/version.c cook/id.c cook/match.c
  19. #   cook/stmt.c
  20. # Wrapped by vixie@efficacy.home.vix.com on Tue May  4 01:36:41 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'Makefile'\"
  24. else
  25. echo shar: Extracting \"'Makefile'\" \(16134 characters\)
  26. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  27. X#
  28. X# You may need to change this for your system.
  29. X# The ``h'' directory supplements your system, not replacing it.
  30. X# The first variation is for gcc when it isn't the native complier,
  31. X# the second variation is for systems with missing ANSI C include files,
  32. X# the third variation is for conforming ANSI C implementations.
  33. X#
  34. X# H = -I/usr/local/lib/gcc-include -I/usr/include -Ih
  35. X# H = -I/usr/include -Ih
  36. XH =
  37. X# H =                # SunOS
  38. X# H =                # ConvexOS
  39. X# H =                # dgux
  40. X# H =                # dcosx
  41. X# H =                # ULTRIX
  42. X
  43. X#
  44. X# the name of the compiler to use
  45. X#
  46. XCC = cc
  47. X# CC = gcc
  48. X# CC = cc            # SunOS
  49. X# CC = cc            # ConvexOS
  50. X# CC = rcc            # SCO
  51. X# CC = cc            # dgux
  52. X# CC = /usr/ucb/cc        # dcosx
  53. X# CC = cc            # ULTRIX
  54. X
  55. X#
  56. X# The compiler flags to use, except for include path.
  57. X#
  58. XCFLAGS = -O
  59. X# CFLAGS = -g
  60. X# CFLAGS = -O            # SunOS
  61. X# CFLAGS = -O            # ConvexOS
  62. X# CFLAGS = -O            # dgux
  63. X# CFLAGS = -O -Xt -U__STDC__    # dcosx
  64. X# CFLAGS = -O -Wall -ansi    # gcc
  65. X# CFLAGS = -O            # ULTRIX
  66. X
  67. X#
  68. X# where to put the library directory
  69. X#
  70. XLIB = /usr/local/lib/cook
  71. X
  72. X#
  73. X# where to put the executables
  74. X#
  75. XBIN = /usr/local/bin
  76. X
  77. X#
  78. X# where to put the manuals
  79. X#
  80. XMAN = /usr/local/man
  81. X
  82. X#
  83. X# Which yacc to use
  84. X#
  85. XYACC = yacc
  86. X# YACC = bison -y        # GNU
  87. X# YACC = byacc            # Berkeley yacc
  88. X
  89. X#
  90. X# extra libraries required for your system
  91. X#
  92. XLIBRARIES =
  93. X# LIBRARIES =            # SunOS
  94. X# LIBRARIES =            # ConvexOS
  95. X# LIBRARIES =            # dgux
  96. X# LIBRARIES = -lucb        # dcosx
  97. X# LIBRARIES =            # ULTRIX
  98. X# LIBRARIES = -lbsd
  99. X
  100. X#
  101. X# shell to use to run tests and commands
  102. X#    Make sure there are no spaces after the definition,
  103. X#    many falavours of make(1) can't cope with them.
  104. X#
  105. XSHELL = /bin/sh
  106. X# SHELL = /bin/sh        # SunOS
  107. X# SHELL = /bin/sh        # ConvexOS
  108. X# SHELL = /bin/sh        # dgux
  109. X# SHELL = /bin/sh        # dcosx
  110. X# SHELL = /bin/sh5        # ULTRIX
  111. X
  112. X# You should not need to alter anything below this point.
  113. X#------------------------------------------------------------
  114. X
  115. Xall: bin/cook bin/c_incl bin/find_libs bin/roffpp bin/cooktime
  116. X
  117. X
  118. Xc_incl/cache.o: c_incl/cache.c common/arglex.h common/main.h \
  119. X        c_incl/cache.h common/str.h common/s-v-arg.h \
  120. X        common/word.h common/error.h common/mem.h c_incl/os.h 
  121. X    $(CC) $(CFLAGS) -Ic_incl -Icommon $(H) -c c_incl/cache.c
  122. X    mv cache.o c_incl
  123. X
  124. Xc_incl/lang_c.o: c_incl/lang_c.c common/error.h common/main.h \
  125. X        common/mem.h c_incl/sniff.h common/trace.h \
  126. X        common/word.h common/str.h common/s-v-arg.h 
  127. X    $(CC) $(CFLAGS) -Ic_incl -Icommon $(H) -c c_incl/lang_c.c
  128. X    mv lang_c.o c_incl
  129. X
  130. Xc_incl/lang_roff.o: c_incl/lang_roff.c common/error.h common/main.h \
  131. X        common/mem.h c_incl/sniff.h common/trace.h \
  132. X        common/word.h common/str.h common/s-v-arg.h 
  133. X    $(CC) $(CFLAGS) -Ic_incl -Icommon $(H) -c c_incl/lang_roff.c
  134. X    mv lang_roff.o c_incl
  135. X
  136. Xc_incl/main.o: c_incl/main.c common/arglex.h common/main.h \
  137. X        c_incl/cache.h common/str.h common/s-v-arg.h \
  138. X        common/word.h common/error.h common/help.h \
  139. X        c_incl/sniff.h common/trace.h common/version.h 
  140. X    $(CC) $(CFLAGS) -Ic_incl -Icommon $(H) -c c_incl/main.c
  141. X    mv main.o c_incl
  142. X
  143. Xc_incl/os.o: c_incl/os.c common/error.h common/main.h c_incl/os.h
  144. X    $(CC) $(CFLAGS) -Ic_incl -Icommon $(H) -c c_incl/os.c
  145. X    mv os.o c_incl
  146. X
  147. Xc_incl/sniff.o: c_incl/sniff.c c_incl/cache.h common/main.h \
  148. X        common/str.h common/s-v-arg.h common/word.h \
  149. X        common/error.h common/mem.h c_incl/os.h c_incl/sniff.h \
  150. X        common/trace.h 
  151. X    $(CC) $(CFLAGS) -Ic_incl -Icommon $(H) -c c_incl/sniff.c
  152. X    mv sniff.o c_incl
  153. X
  154. Xcommon/ansi.o: common/ansi.c common/main.h
  155. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/ansi.c
  156. X    mv ansi.o common
  157. X
  158. Xcommon/arglex.o: common/arglex.c common/main.h common/arglex.h \
  159. X        common/error.h common/word.h common/str.h \
  160. X        common/s-v-arg.h common/mem.h common/trace.h 
  161. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/arglex.c
  162. X    mv arglex.o common
  163. X
  164. Xcommon/error.o: common/error.c common/arglex.h common/main.h \
  165. X        common/error.h common/s-v-arg.h 
  166. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/error.c
  167. X    mv error.o common
  168. X
  169. Xcommon/help.o: common/help.c common/arglex.h common/main.h \
  170. X        common/error.h common/help.h common/patchlevel.h 
  171. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/help.c
  172. X    mv help.o common
  173. X
  174. Xcommon/mem.o: common/mem.c common/mem.h common/main.h common/error.h
  175. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/mem.c
  176. X    mv mem.o common
  177. X
  178. Xcommon/str.o: common/str.c common/error.h common/main.h common/mem.h \
  179. X        common/s-v-arg.h common/str.h 
  180. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/str.c
  181. X    mv str.o common
  182. X
  183. Xcommon/trace.o: common/trace.c common/error.h common/main.h \
  184. X        common/mem.h common/arglex.h common/s-v-arg.h \
  185. X        common/str.h common/trace.h 
  186. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/trace.c
  187. X    mv trace.o common
  188. X
  189. Xcommon/version.o: common/version.c common/arglex.h common/main.h \
  190. X        common/error.h common/help.h common/str.h \
  191. X        common/s-v-arg.h common/version.h 
  192. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/version.c
  193. X    mv version.o common
  194. X
  195. Xcommon/word.o: common/word.c common/error.h common/main.h common/mem.h \
  196. X        common/str.h common/s-v-arg.h common/word.h 
  197. X    $(CC) $(CFLAGS) -Icommon $(H) -c common/word.c
  198. X    mv word.o common
  199. X
  200. Xcook/builtin.o: cook/builtin.c cook/builtin.h common/main.h cook/cook.h \
  201. X        cook/expr.h common/str.h common/s-v-arg.h common/word.h \
  202. X        cook/stmt.h common/error.h cook/glob.h cook/id.h \
  203. X        cook/match.h common/mem.h cook/option.h cook/os.h 
  204. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/builtin.c
  205. X    mv builtin.o cook
  206. X
  207. Xcook/cook.o: cook/cook.c cook/cook.h common/main.h cook/expr.h \
  208. X        common/str.h common/s-v-arg.h common/word.h cook/stmt.h \
  209. X        common/error.h cook/id.h cook/match.h common/mem.h \
  210. X        cook/option.h cook/os.h common/trace.h 
  211. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/cook.c
  212. X    mv cook.o cook
  213. X
  214. Xcook/env.o: cook/env.c common/main.h cook/env.h common/mem.h \
  215. X        common/error.h 
  216. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/env.c
  217. X    mv env.o cook
  218. X
  219. Xcook/expr.o: cook/expr.c cook/builtin.h common/main.h cook/cook.h \
  220. X        cook/expr.h common/str.h common/s-v-arg.h common/word.h \
  221. X        cook/stmt.h common/error.h cook/id.h cook/lex.h \
  222. X        cook/match.h common/mem.h cook/option.h common/trace.h 
  223. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/expr.c
  224. X    mv expr.o cook
  225. X
  226. Xcook/glob.o: cook/glob.c cook/glob.h common/main.h common/word.h \
  227. X        common/str.h common/s-v-arg.h common/trace.h \
  228. X        common/mem.h common/error.h 
  229. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/glob.c
  230. X    mv glob.o cook
  231. X
  232. Xcook/hashline.gen.c cook/hashline.gen.h: cook/hashline.y
  233. X    $(YACC) -d cook/hashline.y
  234. X    sed -e 's/[yY][yY]/hashline_/g' y.tab.c > cook/hashline.gen.c
  235. X    sed -e 's/[yY][yY]/hashline_/g' y.tab.h > cook/hashline.gen.h
  236. X    rm y.tab.c y.tab.h
  237. X
  238. Xcook/hashline.gen.o: cook/hashline.gen.c common/error.h common/main.h \
  239. X        cook/expr.h common/str.h common/s-v-arg.h common/word.h \
  240. X        cook/hashline.h cook/lex.h common/mem.h cook/option.h \
  241. X        cook/os.h common/trace.h 
  242. X    $(CC) $(CFLAGS) -Icook -Icommon $(H) -c cook/hashline.gen.c
  243. X    mv hashline.gen.o cook/hashline.gen.o
  244. X
  245. Xcook/id.o: cook/id.c common/error.h common/main.h common/help.h \
  246. X        cook/id.h common/str.h common/s-v-arg.h common/word.h \
  247. X        common/mem.h cook/option.h 
  248. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/id.c
  249. X    mv id.o cook
  250. X
  251. Xcook/lex.o: cook/lex.c common/error.h common/main.h cook/expr.h \
  252. X        common/str.h common/s-v-arg.h common/word.h \
  253. X        cook/hashline.h cook/id.h cook/lex.h common/mem.h \
  254. X        cook/option.h cook/stmt.h common/trace.h \
  255. X        cook/parse.gen.h cook/hashline.gen.h 
  256. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/lex.c
  257. X    mv lex.o cook
  258. X
  259. Xcook/listing.o: cook/listing.c common/error.h common/main.h \
  260. X        cook/listing.h cook/os.h common/str.h common/s-v-arg.h \
  261. X        common/word.h cook/option.h common/trace.h 
  262. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/listing.c
  263. X    mv listing.o cook
  264. X
  265. Xcook/main.o: cook/main.c common/arglex.h common/main.h cook/builtin.h \
  266. X        cook/cook.h cook/expr.h common/str.h common/s-v-arg.h \
  267. X        common/word.h cook/stmt.h cook/env.h common/error.h \
  268. X        common/help.h cook/id.h cook/lex.h cook/listing.h \
  269. X        cook/option.h cook/parse.h common/trace.h \
  270. X        common/version.h 
  271. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/main.c
  272. X    mv main.o cook
  273. X
  274. Xcook/match.o: cook/match.c common/main.h common/str.h common/s-v-arg.h \
  275. X        cook/match.h common/word.h common/error.h common/mem.h \
  276. X        common/trace.h 
  277. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/match.c
  278. X    mv match.o cook
  279. X
  280. Xcook/option.o: cook/option.c common/main.h cook/option.h common/str.h \
  281. X        common/s-v-arg.h common/word.h common/error.h cook/os.h \
  282. X        common/mem.h 
  283. X    $(CC) $(CFLAGS) -D'LIBDIR="$(LIB)"' -Icook -Icommon $(H) -c \
  284. X        cook/option.c 
  285. X    mv option.o cook
  286. X
  287. Xcook/os.o: cook/os.c common/error.h common/main.h cook/id.h \
  288. X        common/str.h common/s-v-arg.h common/word.h \
  289. X        common/mem.h cook/option.h cook/os.h common/trace.h 
  290. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/os.c
  291. X    mv os.o cook
  292. X
  293. Xcook/parse.gen.c cook/parse.gen.h: cook/parse.y
  294. X    $(YACC) -d cook/parse.y
  295. X    sed -e 's/[yY][yY]/parse_/g' y.tab.c > cook/parse.gen.c
  296. X    sed -e 's/[yY][yY]/parse_/g' y.tab.h > cook/parse.gen.h
  297. X    rm y.tab.c y.tab.h
  298. X
  299. Xcook/parse.gen.o: cook/parse.gen.c cook/cook.h common/main.h \
  300. X        cook/expr.h common/str.h common/s-v-arg.h common/word.h \
  301. X        cook/stmt.h cook/id.h cook/lex.h common/mem.h \
  302. X        cook/option.h cook/parse.h common/trace.h 
  303. X    $(CC) $(CFLAGS) -Icook -Icommon $(H) -c cook/parse.gen.c
  304. X    mv parse.gen.o cook/parse.gen.o
  305. X
  306. Xcook/stmt.o: cook/stmt.c cook/cook.h common/main.h cook/expr.h \
  307. X        common/str.h common/s-v-arg.h common/word.h cook/stmt.h \
  308. X        cook/env.h common/error.h cook/id.h cook/match.h \
  309. X        common/mem.h cook/option.h cook/os.h common/trace.h 
  310. X    $(CC) $(CFLAGS)  -Icook -Icommon $(H) -c cook/stmt.c
  311. X    mv stmt.o cook
  312. X
  313. Xcooktime/date.gen.c cooktime/date.gen.h: cooktime/date.y
  314. X    $(YACC) -d cooktime/date.y
  315. X    sed -e 's/[yY][yY]/date_/g' y.tab.c > cooktime/date.gen.c
  316. X    sed -e 's/[yY][yY]/date_/g' y.tab.h > cooktime/date.gen.h
  317. X    rm y.tab.c y.tab.h
  318. X
  319. Xcooktime/date.gen.o: cooktime/date.gen.c cooktime/date.h common/main.h \
  320. X        common/s-v-arg.h common/trace.h 
  321. X    $(CC) $(CFLAGS) -Icooktime -Icommon $(H) -c cooktime/date.gen.c
  322. X    mv date.gen.o cooktime/date.gen.o
  323. X
  324. Xcooktime/main.o: cooktime/main.c common/arglex.h common/main.h \
  325. X        cooktime/date.h common/error.h common/help.h \
  326. X        common/str.h common/s-v-arg.h common/trace.h \
  327. X        common/version.h common/word.h 
  328. X    $(CC) $(CFLAGS) -Icooktime -Icommon $(H) -c cooktime/main.c
  329. X    mv main.o cooktime
  330. X
  331. Xfind_libs/main.o: find_libs/main.c common/arglex.h common/main.h \
  332. X        common/error.h common/help.h common/mem.h \
  333. X        find_libs/os.h common/str.h common/s-v-arg.h \
  334. X        common/version.h 
  335. X    $(CC) $(CFLAGS) -Ifind_libs -Icommon $(H) -c find_libs/main.c
  336. X    mv main.o find_libs
  337. X
  338. Xfind_libs/os.o: find_libs/os.c common/error.h common/main.h \
  339. X        find_libs/os.h 
  340. X    $(CC) $(CFLAGS) -Ifind_libs -Icommon $(H) -c find_libs/os.c
  341. X    mv os.o find_libs
  342. X
  343. Xroffpp/main.o: roffpp/main.c common/arglex.h common/main.h \
  344. X        common/error.h common/help.h roffpp/preprocess.h \
  345. X        common/str.h common/s-v-arg.h common/trace.h \
  346. X        common/version.h 
  347. X    $(CC) $(CFLAGS) -Iroffpp -Icommon $(H) -c roffpp/main.c
  348. X    mv main.o roffpp
  349. X
  350. Xroffpp/preprocess.o: roffpp/preprocess.c common/error.h common/main.h \
  351. X        common/mem.h roffpp/preprocess.h common/str.h \
  352. X        common/s-v-arg.h common/trace.h common/word.h 
  353. X    $(CC) $(CFLAGS) -Iroffpp -Icommon $(H) -c roffpp/preprocess.c
  354. X    mv preprocess.o roffpp
  355. X
  356. Xt0001a: all test/00/t0001a.sh
  357. X    $(SHELL) test/00/t0001a.sh
  358. X
  359. Xt0002a: all test/00/t0002a.sh
  360. X    $(SHELL) test/00/t0002a.sh
  361. X
  362. Xt0003a: all test/00/t0003a.sh
  363. X    $(SHELL) test/00/t0003a.sh
  364. X
  365. Xt0004a: all test/00/t0004a.sh
  366. X    $(SHELL) test/00/t0004a.sh
  367. X
  368. Xt0005a: all test/00/t0005a.sh
  369. X    $(SHELL) test/00/t0005a.sh
  370. X
  371. Xt0006a: all test/00/t0006a.sh
  372. X    $(SHELL) test/00/t0006a.sh
  373. X
  374. Xt0007a: all test/00/t0007a.sh
  375. X    $(SHELL) test/00/t0007a.sh
  376. X
  377. Xt0008a: all test/00/t0008a.sh
  378. X    $(SHELL) test/00/t0008a.sh
  379. X
  380. Xt0009a: all test/00/t0009a.sh
  381. X    $(SHELL) test/00/t0009a.sh
  382. X
  383. Xt0010a: all test/00/t0010a.sh
  384. X    $(SHELL) test/00/t0010a.sh
  385. X
  386. Xt0011a: all test/00/t0011a.sh
  387. X    $(SHELL) test/00/t0011a.sh
  388. X
  389. Xt0012a: all test/00/t0012a.sh
  390. X    $(SHELL) test/00/t0012a.sh
  391. X
  392. Xt0013a: all test/00/t0013a.sh
  393. X    $(SHELL) test/00/t0013a.sh
  394. X
  395. Xt0014a: all test/00/t0014a.sh
  396. X    $(SHELL) test/00/t0014a.sh
  397. X
  398. Xt0015a: all test/00/t0015a.sh
  399. X    $(SHELL) test/00/t0015a.sh
  400. X
  401. Xt0016a: all test/00/t0016a.sh
  402. X    $(SHELL) test/00/t0016a.sh
  403. X
  404. Xt0017a: all test/00/t0017a.sh
  405. X    $(SHELL) test/00/t0017a.sh
  406. X
  407. Xt0018a: all test/00/t0018a.sh
  408. X    $(SHELL) test/00/t0018a.sh
  409. X
  410. Xt0019a: all test/00/t0019a.sh
  411. X    $(SHELL) test/00/t0019a.sh
  412. X
  413. Xt0020a: all test/00/t0020a.sh
  414. X    $(SHELL) test/00/t0020a.sh
  415. X
  416. Xt0021a: all test/00/t0021a.sh
  417. X    $(SHELL) test/00/t0021a.sh
  418. X
  419. Xt0022a: all test/00/t0022a.sh
  420. X    $(SHELL) test/00/t0022a.sh
  421. X
  422. Xt0023a: all test/00/t0023a.sh
  423. X    $(SHELL) test/00/t0023a.sh
  424. X
  425. Xt0024a: all test/00/t0024a.sh
  426. X    $(SHELL) test/00/t0024a.sh
  427. X
  428. Xt0025a: all test/00/t0025a.sh
  429. X    $(SHELL) test/00/t0025a.sh
  430. X
  431. Xt0026a: all test/00/t0026a.sh
  432. X    $(SHELL) test/00/t0026a.sh
  433. X
  434. Xt0027a: all test/00/t0027a.sh
  435. X    $(SHELL) test/00/t0027a.sh
  436. X
  437. Xt0028a: all test/00/t0028a.sh
  438. X    $(SHELL) test/00/t0028a.sh
  439. X
  440. Xt0029a: all test/00/t0029a.sh
  441. X    $(SHELL) test/00/t0029a.sh
  442. X
  443. Xt0030a: all test/00/t0030a.sh
  444. X    $(SHELL) test/00/t0030a.sh
  445. X
  446. Xt0031a: all test/00/t0031a.sh
  447. X    $(SHELL) test/00/t0031a.sh
  448. X
  449. Xt0032a: all test/00/t0032a.sh
  450. X    $(SHELL) test/00/t0032a.sh
  451. X
  452. Xt0033a: all test/00/t0033a.sh
  453. X    $(SHELL) test/00/t0033a.sh
  454. X
  455. Xt0034a: all test/00/t0034a.sh
  456. X    $(SHELL) test/00/t0034a.sh
  457. X
  458. Xt0035a: all test/00/t0035a.sh
  459. X    $(SHELL) test/00/t0035a.sh
  460. X
  461. Xt0036a: all test/00/t0036a.sh
  462. X    $(SHELL) test/00/t0036a.sh
  463. X
  464. Xt0037a: all test/00/t0037a.sh
  465. X    $(SHELL) test/00/t0037a.sh
  466. X
  467. Xt0038a: all test/00/t0038a.sh
  468. X    $(SHELL) test/00/t0038a.sh
  469. X
  470. Xt0039a: all test/00/t0039a.sh
  471. X    $(SHELL) test/00/t0039a.sh
  472. X
  473. Xt0040a: all test/00/t0040a.sh
  474. X    $(SHELL) test/00/t0040a.sh
  475. X
  476. Xt0041a: all test/00/t0041a.sh
  477. X    $(SHELL) test/00/t0041a.sh
  478. X
  479. XCookObj = cook/builtin.o cook/cook.o cook/env.o cook/expr.o cook/glob.o \
  480. X        cook/hashline.gen.o cook/id.o cook/lex.o cook/listing.o \
  481. X        cook/main.o cook/match.o cook/option.o cook/os.o \
  482. X        cook/parse.gen.o cook/stmt.o 
  483. X
  484. XCommonObj = common/ansi.o common/arglex.o common/error.o common/help.o \
  485. X        common/mem.o common/str.o common/trace.o \
  486. X        common/version.o common/word.o 
  487. X
  488. XCInclObj = c_incl/cache.o c_incl/lang_c.o c_incl/lang_roff.o \
  489. X        c_incl/main.o c_incl/os.o c_incl/sniff.o 
  490. X
  491. XFindLibsObj = find_libs/main.o find_libs/os.o
  492. X
  493. XRoffppObj = roffpp/main.o roffpp/preprocess.o
  494. X
  495. XCooktimeObj = cooktime/date.gen.o cooktime/main.o
  496. X
  497. Xbin/cook: $(CookObj) $(CommonObj)
  498. X    -if [ ! -d bin ]; then mkdir bin; fi
  499. X    $(CC) -o bin/cook $(CookObj) $(CommonObj) $(LIBRARIES)
  500. X
  501. Xbin/c_incl: $(CInclObj) $(CommonObj)
  502. X    -if [ ! -d bin ]; then mkdir bin; fi
  503. X    $(CC) -o bin/c_incl $(CInclObj) $(CommonObj) $(LIBRARIES)
  504. X
  505. Xbin/find_libs: $(FindLibsObj) $(CommonObj)
  506. X    -if [ ! -d bin ]; then mkdir bin; fi
  507. X    $(CC) -o bin/find_libs $(FindLibsObj) $(CommonObj) $(LIBRARIES)
  508. X
  509. Xbin/roffpp: $(RoffppObj) $(CommonObj)
  510. X    -if [ ! -d bin ]; then mkdir bin; fi
  511. X    $(CC) -o bin/roffpp $(RoffppObj) $(CommonObj) $(LIBRARIES)
  512. X
  513. Xbin/cooktime: $(CooktimeObj) $(CommonObj)
  514. X    -if [ ! -d bin ]; then mkdir bin; fi
  515. X    $(CC) -o bin/cooktime $(CooktimeObj) $(CommonObj) $(LIBRARIES)
  516. X
  517. Xsure: t0001a t0002a t0003a t0004a t0005a t0006a t0007a t0008a t0009a \
  518. X        t0010a t0011a t0012a t0013a t0014a t0015a t0016a t0017a \
  519. X        t0018a t0019a t0020a t0021a t0022a t0023a t0024a t0025a \
  520. X        t0026a t0027a t0028a t0029a t0030a t0031a t0032a t0033a \
  521. X        t0034a t0035a t0036a t0037a t0038a t0039a t0040a t0041a 
  522. X    @echo Passed All Tests
  523. X
  524. Xclean:
  525. X    rm -f core c_incl/cache.o c_incl/lang_c.o c_incl/lang_roff.o \
  526. X        c_incl/main.o c_incl/os.o c_incl/sniff.o common/ansi.o \
  527. X        common/arglex.o common/error.o common/help.o \
  528. X        common/mem.o common/str.o common/trace.o \
  529. X        common/version.o common/word.o cook/builtin.o \
  530. X        cook/cook.o cook/env.o cook/expr.o cook/glob.o \
  531. X        cook/hashline.gen.c cook/hashline.gen.h \
  532. X        cook/hashline.gen.o cook/id.o cook/lex.o cook/listing.o \
  533. X        cook/main.o cook/match.o cook/option.o cook/os.o \
  534. X        cook/parse.gen.c cook/parse.gen.h cook/parse.gen.o \
  535. X        cook/stmt.o cooktime/date.gen.c cooktime/date.gen.h \
  536. X        cooktime/date.gen.o cooktime/main.o find_libs/main.o \
  537. X        find_libs/os.o roffpp/main.o roffpp/preprocess.o 
  538. X
  539. Xclobber: clean
  540. X    rm -f bin/cook bin/c_incl bin/find_libs bin/roffpp bin/cooktime
  541. X
  542. Xinstall: all
  543. X    chmod a+x bin/*
  544. X    cp bin/* $(BIN)
  545. X    $(SHELL) man1/install.sh $(MAN)/man1
  546. X    -mkdir $(LIB)
  547. X    -chmod a+rx $(LIB)
  548. X    chmod a+r lib/*
  549. X    cp lib/* $(LIB)
  550. END_OF_FILE
  551. if test 16134 -ne `wc -c <'Makefile'`; then
  552.     echo shar: \"'Makefile'\" unpacked with wrong size!
  553. fi
  554. # end of 'Makefile'
  555. fi
  556. if test -f 'common/version.c' -a "${1}" != "-c" ; then 
  557.   echo shar: Will not clobber existing file \"'common/version.c'\"
  558. else
  559. echo shar: Extracting \"'common/version.c'\" \(17634 characters\)
  560. sed "s/^X//" >'common/version.c' <<'END_OF_FILE'
  561. X/*
  562. X *    cook - a program construction tool
  563. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  564. X *    All rights reserved.
  565. X *
  566. X *    This program is free software; you can redistribute it and/or modify
  567. X *    it under the terms of the GNU General Public License as published by
  568. X *    the Free Software Foundation; either version 2 of the License, or
  569. X *    (at your option) any later version.
  570. X *
  571. X *    This program is distributed in the hope that it will be useful,
  572. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  573. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  574. X *    GNU General Public License for more details.
  575. X *
  576. X *    You should have received a copy of the GNU General Public License
  577. X *    along with this program; if not, write to the Free Software
  578. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  579. X *
  580. X * MANIFEST: functions to provide common -VERSion behaviour
  581. X */
  582. X
  583. X#include <stdio.h>
  584. X#include <stdlib.h>
  585. X
  586. X#include <arglex.h>
  587. X#include <error.h>
  588. X#include <help.h>
  589. X#include <str.h>
  590. X/* #include <trace.h> */
  591. X#include <version.h>
  592. X
  593. X
  594. Xstatic void version_copyright _((void));
  595. X
  596. Xstatic void
  597. Xversion_copyright()
  598. X{
  599. X    static char *text[] =
  600. X    {
  601. X        "%C",
  602. X    };
  603. X    help(text, SIZEOF(text), (void (*)_((void)))0);
  604. X}
  605. X
  606. X
  607. Xstatic void version_redistribution _((void));
  608. X
  609. Xstatic void
  610. Xversion_redistribution()
  611. X{
  612. X    static char *text[] =
  613. X    {
  614. X"            GNU GENERAL PUBLIC LICENSE",
  615. X"   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION",
  616. X"",
  617. X"  0. This License applies to any program or other work which contains",
  618. X"a notice placed by the copyright holder saying it may be distributed",
  619. X"under the terms of this General Public License.  The \"Program\", below,",
  620. X"refers to any such program or work, and a \"work based on the Program\"",
  621. X"means either the Program or any derivative work under copyright law:",
  622. X"that is to say, a work containing the Program or a portion of it,",
  623. X"either verbatim or with modifications and/or translated into another",
  624. X"language.  (Hereinafter, translation is included without limitation in",
  625. X"the term \"modification\".)  Each licensee is addressed as \"you\".",
  626. X"",
  627. X"Activities other than copying, distribution and modification are not",
  628. X"covered by this License; they are outside its scope.  The act of",
  629. X"running the Program is not restricted, and the output from the Program",
  630. X"is covered only if its contents constitute a work based on the",
  631. X"Program (independent of having been made by running the Program).",
  632. X"Whether that is true depends on what the Program does.",
  633. X"",
  634. X"  1. You may copy and distribute verbatim copies of the Program's",
  635. X"source code as you receive it, in any medium, provided that you",
  636. X"conspicuously and appropriately publish on each copy an appropriate",
  637. X"copyright notice and disclaimer of warranty; keep intact all the",
  638. X"notices that refer to this License and to the absence of any warranty;",
  639. X"and give any other recipients of the Program a copy of this License",
  640. X"along with the Program.",
  641. X"",
  642. X"You may charge a fee for the physical act of transferring a copy, and",
  643. X"you may at your option offer warranty protection in exchange for a fee.",
  644. X"",
  645. X"  2. You may modify your copy or copies of the Program or any portion",
  646. X"of it, thus forming a work based on the Program, and copy and",
  647. X"distribute such modifications or work under the terms of Section 1",
  648. X"above, provided that you also meet all of these conditions:",
  649. X"",
  650. X"    a) You must cause the modified files to carry prominent notices",
  651. X"    stating that you changed the files and the date of any change.",
  652. X"",
  653. X"    b) You must cause any work that you distribute or publish, that in",
  654. X"    whole or in part contains or is derived from the Program or any",
  655. X"    part thereof, to be licensed as a whole at no charge to all third",
  656. X"    parties under the terms of this License.",
  657. X"",
  658. X"    c) If the modified program normally reads commands interactively",
  659. X"    when run, you must cause it, when started running for such",
  660. X"    interactive use in the most ordinary way, to print or display an",
  661. X"    announcement including an appropriate copyright notice and a",
  662. X"    notice that there is no warranty (or else, saying that you provide",
  663. X"    a warranty) and that users may redistribute the program under",
  664. X"    these conditions, and telling the user how to view a copy of this",
  665. X"    License.  (Exception: if the Program itself is interactive but",
  666. X"    does not normally print such an announcement, your work based on",
  667. X"    the Program is not required to print an announcement.)",
  668. X"",
  669. X"These requirements apply to the modified work as a whole.  If",
  670. X"identifiable sections of that work are not derived from the Program,",
  671. X"and can be reasonably considered independent and separate works in",
  672. X"themselves, then this License, and its terms, do not apply to those",
  673. X"sections when you distribute them as separate works.  But when you",
  674. X"distribute the same sections as part of a whole which is a work based",
  675. X"on the Program, the distribution of the whole must be on the terms of",
  676. X"this License, whose permissions for other licensees extend to the",
  677. X"entire whole, and thus to each and every part regardless of who wrote it.",
  678. X"",
  679. X"Thus, it is not the intent of this section to claim rights or contest",
  680. X"your rights to work written entirely by you; rather, the intent is to",
  681. X"exercise the right to control the distribution of derivative or",
  682. X"collective works based on the Program.",
  683. X"",
  684. X"In addition, mere aggregation of another work not based on the Program",
  685. X"with the Program (or with a work based on the Program) on a volume of",
  686. X"a storage or distribution medium does not bring the other work under",
  687. X"the scope of this License.",
  688. X"",
  689. X"  3. You may copy and distribute the Program (or a work based on it,",
  690. X"under Section 2) in object code or executable form under the terms of",
  691. X"Sections 1 and 2 above provided that you also do one of the following:",
  692. X"",
  693. X"    a) Accompany it with the complete corresponding machine-readable",
  694. X"    source code, which must be distributed under the terms of Sections",
  695. X"    1 and 2 above on a medium customarily used for software interchange; or,",
  696. X"",
  697. X"    b) Accompany it with a written offer, valid for at least three",
  698. X"    years, to give any third party, for a charge no more than your",
  699. X"    cost of physically performing source distribution, a complete",
  700. X"    machine-readable copy of the corresponding source code, to be",
  701. X"    distributed under the terms of Sections 1 and 2 above on a medium",
  702. X"    customarily used for software interchange; or,",
  703. X"",
  704. X"    c) Accompany it with the information you received as to the offer",
  705. X"    to distribute corresponding source code.  (This alternative is",
  706. X"    allowed only for noncommercial distribution and only if you",
  707. X"    received the program in object code or executable form with such",
  708. X"    an offer, in accord with Subsection b above.)",
  709. X"",
  710. X"The source code for a work means the preferred form of the work for",
  711. X"making modifications to it.  For an executable work, complete source",
  712. X"code means all the source code for all modules it contains, plus any",
  713. X"associated interface definition files, plus the scripts used to",
  714. X"control compilation and installation of the executable.  However, as a",
  715. X"special exception, the source code distributed need not include",
  716. X"anything that is normally distributed (in either source or binary",
  717. X"form) with the major components (compiler, kernel, and so on) of the",
  718. X"operating system on which the executable runs, unless that component",
  719. X"itself accompanies the executable.",
  720. X"",
  721. X"If distribution of executable or object code is made by offering",
  722. X"access to copy from a designated place, then offering equivalent",
  723. X"access to copy the source code from the same place counts as",
  724. X"distribution of the source code, even though third parties are not",
  725. X"compelled to copy the source along with the object code.",
  726. X"",
  727. X"  4. You may not copy, modify, sublicense, or distribute the Program",
  728. X"except as expressly provided under this License.  Any attempt",
  729. X"otherwise to copy, modify, sublicense or distribute the Program is",
  730. X"void, and will automatically terminate your rights under this License.",
  731. X"However, parties who have received copies, or rights, from you under",
  732. X"this License will not have their licenses terminated so long as such",
  733. X"parties remain in full compliance.",
  734. X"",
  735. X"  5. You are not required to accept this License, since you have not",
  736. X"signed it.  However, nothing else grants you permission to modify or",
  737. X"distribute the Program or its derivative works.  These actions are",
  738. X"prohibited by law if you do not accept this License.  Therefore, by",
  739. X"modifying or distributing the Program (or any work based on the",
  740. X"Program), you indicate your acceptance of this License to do so, and",
  741. X"all its terms and conditions for copying, distributing or modifying",
  742. X"the Program or works based on it.",
  743. X"",
  744. X"  6. Each time you redistribute the Program (or any work based on the",
  745. X"Program), the recipient automatically receives a license from the",
  746. X"original licensor to copy, distribute or modify the Program subject to",
  747. X"these terms and conditions.  You may not impose any further",
  748. X"restrictions on the recipients' exercise of the rights granted herein.",
  749. X"You are not responsible for enforcing compliance by third parties to",
  750. X"this License.",
  751. X"",
  752. X"  7. If, as a consequence of a court judgment or allegation of patent",
  753. X"infringement or for any other reason (not limited to patent issues),",
  754. X"conditions are imposed on you (whether by court order, agreement or",
  755. X"otherwise) that contradict the conditions of this License, they do not",
  756. X"excuse you from the conditions of this License.  If you cannot",
  757. X"distribute so as to satisfy simultaneously your obligations under this",
  758. X"License and any other pertinent obligations, then as a consequence you",
  759. X"may not distribute the Program at all.  For example, if a patent",
  760. X"license would not permit royalty-free redistribution of the Program by",
  761. X"all those who receive copies directly or indirectly through you, then",
  762. X"the only way you could satisfy both it and this License would be to",
  763. X"refrain entirely from distribution of the Program.",
  764. X"",
  765. X"If any portion of this section is held invalid or unenforceable under",
  766. X"any particular circumstance, the balance of the section is intended to",
  767. X"apply and the section as a whole is intended to apply in other",
  768. X"circumstances.",
  769. X"",
  770. X"It is not the purpose of this section to induce you to infringe any",
  771. X"patents or other property right claims or to contest validity of any",
  772. X"such claims; this section has the sole purpose of protecting the",
  773. X"integrity of the free software distribution system, which is",
  774. X"implemented by public license practices.  Many people have made",
  775. X"generous contributions to the wide range of software distributed",
  776. X"through that system in reliance on consistent application of that",
  777. X"system; it is up to the author/donor to decide if he or she is willing",
  778. X"to distribute software through any other system and a licensee cannot",
  779. X"impose that choice.",
  780. X"",
  781. X"This section is intended to make thoroughly clear what is believed to",
  782. X"be a consequence of the rest of this License.",
  783. X"",
  784. X"  8. If the distribution and/or use of the Program is restricted in",
  785. X"certain countries either by patents or by copyrighted interfaces, the",
  786. X"original copyright holder who places the Program under this License",
  787. X"may add an explicit geographical distribution limitation excluding",
  788. X"those countries, so that distribution is permitted only in or among",
  789. X"countries not thus excluded.  In such case, this License incorporates",
  790. X"the limitation as if written in the body of this License.",
  791. X"",
  792. X"  9. The Free Software Foundation may publish revised and/or new versions",
  793. X"of the General Public License from time to time.  Such new versions will",
  794. X"be similar in spirit to the present version, but may differ in detail to",
  795. X"address new problems or concerns.",
  796. X"",
  797. X"Each version is given a distinguishing version number.  If the Program",
  798. X"specifies a version number of this License which applies to it and \"any",
  799. X"later version\", you have the option of following the terms and conditions",
  800. X"either of that version or of any later version published by the Free",
  801. X"Software Foundation.  If the Program does not specify a version number of",
  802. X"this License, you may choose any version ever published by the Free Software",
  803. X"Foundation.",
  804. X"",
  805. X"  10. If you wish to incorporate parts of the Program into other free",
  806. X"programs whose distribution conditions are different, write to the author",
  807. X"to ask for permission.  For software which is copyrighted by the Free",
  808. X"Software Foundation, write to the Free Software Foundation; we sometimes",
  809. X"make exceptions for this.  Our decision will be guided by the two goals",
  810. X"of preserving the free status of all derivatives of our free software and",
  811. X"of promoting the sharing and reuse of software generally.",
  812. X    };
  813. X    help(text, SIZEOF(text), (void (*)_((void)))0);
  814. X}
  815. X
  816. X
  817. Xstatic void version_warranty _((void));
  818. X
  819. Xstatic void
  820. Xversion_warranty()
  821. X{
  822. X    static char *text[] =
  823. X    {
  824. X"                NO WARRANTY",
  825. X"",
  826. X"  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY",
  827. X"FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN",
  828. X"OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES",
  829. X"PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED",
  830. X"OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF",
  831. X"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS",
  832. X"TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE",
  833. X"PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,",
  834. X"REPAIR OR CORRECTION.",
  835. X"",
  836. X"  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING",
  837. X"WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR",
  838. X"REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,",
  839. X"INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING",
  840. X"OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED",
  841. X"TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY",
  842. X"YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER",
  843. X"PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE",
  844. X"POSSIBILITY OF SUCH DAMAGES.",
  845. X    };
  846. X
  847. X    help(text, SIZEOF(text), (void (*)_((void)))0);
  848. X}
  849. X
  850. X
  851. Xstatic void version_usage _((void));
  852. X
  853. Xstatic void
  854. Xversion_usage()
  855. X{
  856. X    fprintf(stderr, "usage: %s -VERSion [ <info-name> ]\n", progname);
  857. X    fprintf(stderr, "       %s -VERSion -Help\n", progname);
  858. X    exit(1);
  859. X}
  860. X
  861. X
  862. Xtypedef struct table_ty table_ty;
  863. Xstruct table_ty
  864. X{
  865. X    char    *name;
  866. X    void    (*func)_((void));
  867. X};
  868. X
  869. X
  870. Xstatic table_ty table[] =
  871. X{
  872. X    { "Copyright",        version_copyright,    },
  873. X    { "Redistribution",    version_redistribution,    },
  874. X    { "Warranty",        version_warranty,    },
  875. X};
  876. X
  877. X
  878. Xstatic void version_main _((void));
  879. X
  880. Xstatic void
  881. Xversion_main()
  882. X{
  883. X    void    (*func)_((void));
  884. X
  885. X    /* trace(("version_main()\n{\n"/ *}* /)); */
  886. X    if (arglex_token == arglex_token_string)
  887. X    {
  888. X        int        nhit;
  889. X        table_ty    *tp;
  890. X        string_ty    *s1;
  891. X        string_ty    *s2;
  892. X        table_ty    *hit[SIZEOF(table)];
  893. X        int        j;
  894. X
  895. X        nhit = 0;
  896. X        for (tp = table; tp < ENDOF(table); ++tp)
  897. X        {
  898. X            if (arglex_compare(tp->name, arglex_value.alv_string))
  899. X                hit[nhit++] = tp;
  900. X        }
  901. X        switch (nhit)
  902. X        {
  903. X        case 0:
  904. X            fatal
  905. X            (
  906. X                "version information name \"%s\" unknown",
  907. X                arglex_value.alv_string
  908. X            );
  909. X    
  910. X        case 1:
  911. X            break;
  912. X    
  913. X        default:
  914. X            s1 = str_from_c(hit[0]->name);
  915. X            for (j = 1; j < nhit; ++j)
  916. X            {
  917. X                s2 = str_format("%S, %s", s1, hit[j]->name);
  918. X                str_free(s1);
  919. X                s1 = s2;
  920. X            }
  921. X            fatal("version information name \"%s\" ambiguous (%s)", arglex_value.alv_string, s1->str_text);
  922. X        }
  923. X        arglex();
  924. X        func = hit[0]->func;
  925. X    }
  926. X    else
  927. X        func = version_copyright;
  928. X    if (arglex_token != arglex_token_eoln)
  929. X    {
  930. X        error
  931. X        (
  932. X            "misplaced \"%s\" command line argument",
  933. X            arglex_value.alv_string
  934. X        );
  935. X        version_usage();
  936. X    }
  937. X
  938. X    func();
  939. X    /* trace((/ *{* /"}\n")); */
  940. X}
  941. X
  942. X
  943. Xstatic void version_help _((void));
  944. X
  945. Xstatic void
  946. Xversion_help()
  947. X{
  948. X    static char *text[] = 
  949. X    {
  950. X"NAME",
  951. X"    %s -VERSion - give version information",
  952. X"",
  953. X"SYNOPSIS",
  954. X"    %s -VERSion [ <info-name> ]",
  955. X"    %s -VERSion -Help",
  956. X"",
  957. X"DESCRIPTION",
  958. X"    The %s -VERSion command is used to give version",
  959. X"    information and conditions of use.",
  960. X"",
  961. X"    There are a number of possible info-names, as follow",
  962. X"    (abbreviations as for command line options):",
  963. X"",
  964. X"    Copyright",
  965. X"        The copyright notice for the %s program.  Version",
  966. X"        information will also be printed.",
  967. X"        This is the default.",
  968. X"",
  969. X"    Redistribution",
  970. X"        Print the conditions of use and redistribution.",
  971. X"",
  972. X"    Warranty",
  973. X"        Print the limited warranty.",
  974. X"",
  975. X"OPTIONS",
  976. X"    The following options are understood:",
  977. X"",
  978. X"    -Help",
  979. X"        This option may be used to obtain more",
  980. X"        information about how to use the %s program.",
  981. X"",
  982. X"    All options are case insensitive.  Options may be",
  983. X"    abbreviated; the abbreviation is the upper case letters.",
  984. X"    Options and other command line arguments may be mixed",
  985. X"    arbitrarily on the command line.",
  986. X"",
  987. X"ERRORS",
  988. X"    It is an error if the info-name given is unknown.",
  989. X"",
  990. X"EXIT STATUS",
  991. X"    The %s command will exit with a status of 1 on any",
  992. X"    error.    The %s command will only exit with a status of",
  993. X"    0 if there are no errors.",
  994. X"",
  995. X"COPYRIGHT",
  996. X"    %C",
  997. X"",
  998. X"AUTHOR",
  999. X"    %A",
  1000. X    };
  1001. X
  1002. X    help(text, SIZEOF(text), version_usage);
  1003. X}
  1004. X
  1005. X
  1006. Xvoid
  1007. Xversion()
  1008. X{
  1009. X    /* trace(("version()\n{\n"/ *}* /)); */
  1010. X    switch (arglex())
  1011. X    {
  1012. X    default:
  1013. X        version_main();
  1014. X        break;
  1015. X
  1016. X    case arglex_token_help:
  1017. X        version_help();
  1018. X        break;
  1019. X    }
  1020. X    /* trace((/ *{* /"}\n")); */
  1021. X}
  1022. END_OF_FILE
  1023. if test 17634 -ne `wc -c <'common/version.c'`; then
  1024.     echo shar: \"'common/version.c'\" unpacked with wrong size!
  1025. fi
  1026. # end of 'common/version.c'
  1027. fi
  1028. if test -f 'cook/id.c' -a "${1}" != "-c" ; then 
  1029.   echo shar: Will not clobber existing file \"'cook/id.c'\"
  1030. else
  1031. echo shar: Extracting \"'cook/id.c'\" \(15314 characters\)
  1032. sed "s/^X//" >'cook/id.c' <<'END_OF_FILE'
  1033. X/*
  1034. X *    cook - file construction tool
  1035. X *    Copyright (C) 1990, 1991, 1992, 1993 Peter Miller.
  1036. X *    All rights reserved.
  1037. X *
  1038. X *    This program is free software; you can redistribute it and/or modify
  1039. X *    it under the terms of the GNU General Public License as published by
  1040. X *    the Free Software Foundation; either version 2 of the License, or
  1041. X *    (at your option) any later version.
  1042. X *
  1043. X *    This program is distributed in the hope that it will be useful,
  1044. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1045. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1046. X *    GNU General Public License for more details.
  1047. X *
  1048. X *    You should have received a copy of the GNU General Public License
  1049. X *    along with this program; if not, write to the Free Software
  1050. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1051. X *
  1052. X * MANIFEST: functions to manipulate the symbol table
  1053. X */
  1054. X
  1055. X#include <sys/types.h>
  1056. X#include <sys/stat.h>
  1057. X
  1058. X#include <stddef.h>
  1059. X#include <stdlib.h>
  1060. X
  1061. X#include <error.h>
  1062. X#include <help.h>
  1063. X#include <id.h>
  1064. X#include <mem.h>
  1065. X#include <option.h>
  1066. X#include <word.h>
  1067. X
  1068. X/*
  1069. X * identifier manipulation functions
  1070. X *
  1071. X * This file contains the functions for
  1072. X * assigning and referencing variables.
  1073. X */
  1074. X
  1075. X
  1076. X#define HEADER                \
  1077. X    string_ty    *id_name;    \
  1078. X    str_hash_ty    id_hash;    \
  1079. X    id        *id_next;    \
  1080. X    id_class_ty    id_class;
  1081. X
  1082. Xtypedef struct id id;
  1083. Xstruct id
  1084. X{
  1085. X    HEADER
  1086. X};
  1087. X
  1088. Xtypedef struct id_wlist id_wlist;
  1089. Xstruct id_wlist
  1090. X{
  1091. X    HEADER
  1092. X    wlist        id_value;
  1093. X};
  1094. X
  1095. Xtypedef struct id_bifp id_bifp;
  1096. Xstruct id_bifp
  1097. X{
  1098. X    HEADER
  1099. X    bifp        id_value;
  1100. X};
  1101. X
  1102. Xtypedef struct id_stat id_stat;
  1103. Xstruct id_stat
  1104. X{
  1105. X    HEADER
  1106. X    struct stat    id_value;
  1107. X};
  1108. X
  1109. Xtypedef struct id_int id_int;
  1110. Xstruct id_int
  1111. X{
  1112. X    HEADER
  1113. X    int        id_value;
  1114. X};
  1115. X
  1116. X    string_ty    *id_need;
  1117. X    string_ty    *id_younger;
  1118. X    string_ty    *id_target;
  1119. X    string_ty    *id_friend;
  1120. X    string_ty    *id_search_list;
  1121. Xstatic    id        **hash_table;
  1122. Xstatic    str_hash_ty    hash_modulus;
  1123. Xstatic    str_hash_ty    hash_cutover;
  1124. Xstatic    str_hash_ty    hash_cutover_mask;
  1125. Xstatic    str_hash_ty    hash_cutover_split_mask;
  1126. Xstatic    str_hash_ty    hash_split;
  1127. Xstatic    str_hash_ty    hash_load;
  1128. X
  1129. X
  1130. X/*
  1131. X * NAME
  1132. X *    id_initialize - start up symbol table
  1133. X *
  1134. X * SYNOPSIS
  1135. X *    void id_initialize(void);
  1136. X *
  1137. X * DESCRIPTION
  1138. X *    The id_initialize function is used to create the hash table.
  1139. X *
  1140. X * RETURNS
  1141. X *    void
  1142. X *
  1143. X * CAVEAT
  1144. X *    Assumes the str_initialize function has been called already.
  1145. X */
  1146. X
  1147. Xvoid
  1148. Xid_initialize()
  1149. X{
  1150. X    str_hash_ty    j;
  1151. X    wlist        wl;
  1152. X    string_ty    *s;
  1153. X
  1154. X    id_need = str_from_c("need");
  1155. X    id_younger = str_from_c("younger");
  1156. X    id_target = str_from_c("target");
  1157. X    id_friend = str_from_c("targets");
  1158. X    id_search_list = str_from_c("search_list");
  1159. X
  1160. X    hash_modulus = 1 << 8; /* MUST be a power of 2 */
  1161. X    hash_cutover = hash_modulus;
  1162. X    hash_split = hash_modulus - hash_cutover;
  1163. X    hash_cutover_mask = hash_cutover - 1;
  1164. X    hash_cutover_split_mask = (hash_cutover * 2) - 1;
  1165. X    hash_load = 0;
  1166. X    hash_table = (id **)mem_alloc(hash_modulus * sizeof(id*));
  1167. X    for (j = 0; j < hash_modulus; ++j)
  1168. X        hash_table[j] = 0;
  1169. X
  1170. X    /*
  1171. X     * set the "version" predefined variable
  1172. X     */
  1173. X    wl_zero(&wl);
  1174. X    s = str_from_c("version");
  1175. X    wl_append(&wl, s);
  1176. X    str_free(s);
  1177. X    s = str_from_c(version_stamp());
  1178. X    wl_append(&wl, s);
  1179. X    str_free(s);
  1180. X    s = str_from_c("version");
  1181. X    id_assign(s, ID_CLASS_VARIABLE, &wl);
  1182. X    str_free(s);
  1183. X    wl_free(&wl);
  1184. X
  1185. X    /*
  1186. X     * set the "self" predefined variable
  1187. X     */
  1188. X    s = str_from_c(progname);
  1189. X    wl_append(&wl, s);
  1190. X    str_free(s);
  1191. X    s = str_from_c("self");
  1192. X    id_assign(s, ID_CLASS_VARIABLE, &wl);
  1193. X    str_free(s);
  1194. X    wl_free(&wl);
  1195. X
  1196. X#ifdef __STDC__
  1197. X    /*
  1198. X     * This symbol is only defined if we have a conforming C
  1199. X     * compiler.  This is support for the C recipes.
  1200. X     */
  1201. X    wl_append(&wl, str_true);
  1202. X    s = str_from_c("__STDC__");
  1203. X    id_assign(s, ID_CLASS_VARIABLE, &wl);
  1204. X    str_free(s);
  1205. X    wl_free(&wl);
  1206. X#endif
  1207. X    
  1208. X    /*
  1209. X     * set the default search list
  1210. X     * in the "search_list" predefined variable
  1211. X     */
  1212. X    s = str_from_c(".");
  1213. X    wl_append(&wl, s);
  1214. X    str_free(s);
  1215. X    id_assign(id_search_list, ID_CLASS_VARIABLE, &wl);
  1216. X    wl_free(&wl);
  1217. X}
  1218. X
  1219. X
  1220. X/*
  1221. X * NAME
  1222. X *    split - reduce symbol table load
  1223. X *
  1224. X * SYNOPSIS
  1225. X *    void split(void);
  1226. X *
  1227. X * DESCRIPTION
  1228. X *    The split function is used to split symbols in the bucket indicated by
  1229. X *    the split point.  The symbols are split between that bucket and the one
  1230. X *    after the current end of the table.
  1231. X *
  1232. X * RETURNS
  1233. X *    void
  1234. X *
  1235. X * CAVEAT
  1236. X *    It is only sensable to do this when the symbol table load exceeds some
  1237. X *    reasonable threshold.  A threshold of 80% is suggested.
  1238. X */
  1239. X
  1240. Xstatic void split _((void));
  1241. X
  1242. Xstatic void
  1243. Xsplit()
  1244. X{
  1245. X    id        *p;
  1246. X    id        **ipp;
  1247. X    id        *p2;
  1248. X    str_hash_ty    index;
  1249. X
  1250. X    /*
  1251. X     * get the list to be split across buckets 
  1252. X     */
  1253. X    p = hash_table[hash_split];
  1254. X    hash_table[hash_split] = 0;
  1255. X
  1256. X    /*
  1257. X     * increase the modulus by one
  1258. X     */
  1259. X    hash_modulus++;
  1260. X    mem_change_size((char **)&hash_table, hash_modulus * sizeof(id*));
  1261. X    hash_table[hash_modulus - 1] = 0;
  1262. X    hash_split = hash_modulus - hash_cutover;
  1263. X    if (hash_split >= hash_cutover)
  1264. X    {
  1265. X        hash_cutover = hash_modulus;
  1266. X        hash_split = 0;
  1267. X        hash_cutover_mask = hash_cutover - 1;
  1268. X        hash_cutover_split_mask = (hash_cutover * 2) - 1;
  1269. X    }
  1270. X
  1271. X    /*
  1272. X     * now redistribute the list elements
  1273. X     *
  1274. X     * It is important to preserve the order of the links because they can be
  1275. X     * push-down stacks, and to simply add them to the head of the list will
  1276. X     * reverse the order of the stack!
  1277. X     */
  1278. X    while (p)
  1279. X    {
  1280. X        p2 = p;
  1281. X        p = p2->id_next;
  1282. X        p2->id_next = 0;
  1283. X
  1284. X        index = p2->id_hash & hash_cutover_mask;
  1285. X        if (index < hash_split)
  1286. X            index = p2->id_hash & hash_cutover_split_mask;
  1287. X        for (ipp = &hash_table[index]; *ipp; ipp = &(*ipp)->id_next)
  1288. X            ;
  1289. X        *ipp = p2;
  1290. X    }
  1291. X}
  1292. X
  1293. X
  1294. X/*
  1295. X * NAME
  1296. X *    copy - copy a symbol value
  1297. X *
  1298. X * SYNOPSIS
  1299. X *    void copy(id *p, void *arg);
  1300. X *
  1301. X * DESCRIPTION
  1302. X *    The copy function is used to copy the passed value of a symbol into the
  1303. X *    storage of that symbol.
  1304. X *
  1305. X * RETURNS
  1306. X *    void
  1307. X */
  1308. X
  1309. Xstatic void copy _((id *, void *));
  1310. X
  1311. Xstatic void
  1312. Xcopy(p, arg)
  1313. X    id        *p;
  1314. X    void        *arg;
  1315. X{
  1316. X    switch ((int)p->id_class)
  1317. X    {
  1318. X    default:
  1319. X        fatal("illegal id class %d (bug)", p->id_class);
  1320. X
  1321. X    case ID_CLASS_VARIABLE:
  1322. X        {
  1323. X            id_wlist    *ip;
  1324. X            wlist        *value;
  1325. X
  1326. X            ip = (id_wlist *)p;
  1327. X            value = (wlist *)arg;
  1328. X            wl_zero(value);
  1329. X            wl_copy(value, &ip->id_value);
  1330. X        }
  1331. X        break;
  1332. X
  1333. X    case ID_CLASS_ALREADY:
  1334. X    case ID_CLASS_FLAGS:
  1335. X    case ID_CLASS_HASH_KEYWORD:
  1336. X    case ID_CLASS_PARSE_KEYWORD:
  1337. X        {
  1338. X            id_int        *ip;
  1339. X            int        *value;
  1340. X
  1341. X            ip = (id_int *)p;
  1342. X            value = (int *)arg;
  1343. X            *value = ip->id_value;
  1344. X        }
  1345. X        break;
  1346. X
  1347. X    case ID_CLASS_BUILTIN:
  1348. X        {
  1349. X            id_bifp        *ip;
  1350. X            bifp        *value;
  1351. X
  1352. X            ip = (id_bifp *)p;
  1353. X            value = (bifp *)arg;
  1354. X            *value = ip->id_value;
  1355. X        }
  1356. X        break;
  1357. X
  1358. X    case ID_CLASS_STAT:
  1359. X        {
  1360. X            id_stat        *ip;
  1361. X            struct stat    *value;
  1362. X
  1363. X            ip = (id_stat *)p;
  1364. X            value = (struct stat *)arg;
  1365. X            *value = ip->id_value;
  1366. X        }
  1367. X        break;
  1368. X    }
  1369. X}
  1370. X
  1371. X
  1372. X/*
  1373. X * NAME
  1374. X *    id_search - search for a variable
  1375. X *
  1376. X * SYNOPSIS
  1377. X *    int id_search(string_ty *name, wlist *value);
  1378. X *
  1379. X * DESCRIPTION
  1380. X *    Id_search is used to reference a variable.
  1381. X *
  1382. X * RETURNS
  1383. X *    If the variable has been defined, the function returns a non-zero value
  1384. X *    and the value is returned through the 'value' pointer.
  1385. X *    If the variable has not been defined, it returns zero,
  1386. X *    and 'value' is unaltered.
  1387. X *
  1388. X * CAVEAT
  1389. X *    The value returned from this function, when returned, is allocated
  1390. X *    in dynamic memory (it is a copy of the value remembered by this module).
  1391. X *    It is the responsibility of the caller to free it when finished with,
  1392. X *    by a wl_free() call.
  1393. X */
  1394. X
  1395. X/*VARARGS2*/
  1396. Xint
  1397. Xid_search(name, class, arg)
  1398. X    string_ty    *name;
  1399. X    id_class_ty    class;
  1400. X    void        *arg;
  1401. X{
  1402. X    str_hash_ty    myhash;
  1403. X    str_hash_ty    index;
  1404. X    id        *p;
  1405. X
  1406. X    myhash = name->str_hash + (int)class;
  1407. X    index = myhash & hash_cutover_mask;
  1408. X    if (index < hash_split)
  1409. X        index = myhash & hash_cutover_split_mask;
  1410. X    for (p = hash_table[index]; p; p = p->id_next)
  1411. X    {
  1412. X        if (p->id_class == class && str_equal(name, p->id_name))
  1413. X        {
  1414. X            copy(p, arg);
  1415. X            return 1;
  1416. X        }
  1417. X    }
  1418. X    return 0;
  1419. X}
  1420. X
  1421. X
  1422. X/*
  1423. X * NAME
  1424. X *    stomp - release symbol value
  1425. X *
  1426. X * SYNOPSIS
  1427. X *    void stomp(id *p);
  1428. X *
  1429. X * DESCRIPTION
  1430. X *    The stomp function is used to release the value of a symbol.
  1431. X *
  1432. X * RETURNS
  1433. X *    void
  1434. X */
  1435. X
  1436. Xstatic void stomp _((id *));
  1437. X
  1438. Xstatic void
  1439. Xstomp(p)
  1440. X    id        *p;
  1441. X{
  1442. X    switch ((int)p->id_class)
  1443. X    {
  1444. X    default:
  1445. X        fatal("illegal id class %d (bug)", p->id_class);
  1446. X
  1447. X    case ID_CLASS_VARIABLE:
  1448. X        {
  1449. X            id_wlist    *ip;
  1450. X
  1451. X            ip = (id_wlist*)p;
  1452. X            wl_free(&ip->id_value);
  1453. X        }
  1454. X        break;
  1455. X
  1456. X    case ID_CLASS_ALREADY:
  1457. X    case ID_CLASS_BUILTIN:
  1458. X    case ID_CLASS_FLAGS:
  1459. X    case ID_CLASS_HASH_KEYWORD:
  1460. X    case ID_CLASS_PARSE_KEYWORD:
  1461. X    case ID_CLASS_STAT:
  1462. X        break;
  1463. X    }
  1464. X}
  1465. X
  1466. X
  1467. X/*
  1468. X * NAME
  1469. X *    assign - set value of symbol
  1470. X *
  1471. X * SYNOPSIS
  1472. X *    void assign(id *p, void *arg);
  1473. X *
  1474. X * DESCRIPTION
  1475. X *    The assign function is used to change the value of a symbol.
  1476. X *
  1477. X * RETURNS
  1478. X *    void
  1479. X *
  1480. X * CAVEAT
  1481. X *    The value is not released first, so use stomp if necessary.
  1482. X */
  1483. X
  1484. Xstatic void assign _((id *, void *));
  1485. X
  1486. Xstatic void
  1487. Xassign(p, arg)
  1488. X    id        *p;
  1489. X    void        *arg;
  1490. X{
  1491. X    switch ((int)p->id_class)
  1492. X    {
  1493. X    default:
  1494. X        fatal("illegal id class %d (bug)", p->id_class);
  1495. X
  1496. X    case ID_CLASS_VARIABLE:
  1497. X        {
  1498. X            id_wlist    *ip;
  1499. X            wlist        *value;
  1500. X
  1501. X            value = (wlist *)arg;
  1502. X            ip = (id_wlist *)p;
  1503. X            wl_copy(&ip->id_value, value);
  1504. X        }
  1505. X        break;
  1506. X
  1507. X    case ID_CLASS_ALREADY:
  1508. X    case ID_CLASS_FLAGS:
  1509. X    case ID_CLASS_HASH_KEYWORD:
  1510. X    case ID_CLASS_PARSE_KEYWORD:
  1511. X        {
  1512. X            id_int        *ip;
  1513. X            int        *value;
  1514. X
  1515. X            value = (int *)arg;
  1516. X            ip = (id_int *)p;
  1517. X            ip->id_value = *value;
  1518. X        }
  1519. X        break;
  1520. X
  1521. X    case ID_CLASS_BUILTIN:
  1522. X        {
  1523. X            id_bifp        *ip;
  1524. X            bifp        value;
  1525. X
  1526. X            value = (bifp)arg;
  1527. X            ip = (id_bifp *)p;
  1528. X            ip->id_value = value;
  1529. X        }
  1530. X        break;
  1531. X
  1532. X    case ID_CLASS_STAT:
  1533. X        {
  1534. X            id_stat        *ip;
  1535. X            struct stat    *value;
  1536. X
  1537. X            value = (struct stat *)arg;
  1538. X            ip = (id_stat*)p;
  1539. X            ip->id_value = *value;
  1540. X        }
  1541. X        break;
  1542. X    }
  1543. X}
  1544. X
  1545. X
  1546. X/*
  1547. X * NAME
  1548. X *    size_by_class - determine symbol size
  1549. X *
  1550. X * SYNOPSIS
  1551. X *    void size_by_class(id_class_ty class);
  1552. X *
  1553. X * DESCRIPTION
  1554. X *    The size_by_class function is used to determine the correct size to
  1555. X *    allocate for symbol storage.
  1556. X *
  1557. X * RETURNS
  1558. X *    size_t: the correct size to malloc.
  1559. X *
  1560. X * CAVEAT
  1561. X *    Never malloc(sizeof(id)) as this will be too small.
  1562. X */
  1563. X
  1564. Xstatic size_t size_by_class _((id_class_ty));
  1565. X
  1566. Xstatic size_t
  1567. Xsize_by_class(class)
  1568. X    id_class_ty    class;
  1569. X{
  1570. X    switch ((int)class)
  1571. X    {
  1572. X    default:
  1573. X        fatal("illegal id class %d (bug)", class);
  1574. X
  1575. X    case ID_CLASS_VARIABLE:
  1576. X        return sizeof(id_wlist);
  1577. X
  1578. X    case ID_CLASS_BUILTIN:
  1579. X        return sizeof(id_bifp);
  1580. X
  1581. X    case ID_CLASS_STAT:
  1582. X        return sizeof(id_stat);
  1583. X
  1584. X    case ID_CLASS_ALREADY:
  1585. X    case ID_CLASS_FLAGS:
  1586. X    case ID_CLASS_HASH_KEYWORD:
  1587. X    case ID_CLASS_PARSE_KEYWORD:
  1588. X        return sizeof(id_int);
  1589. X    }
  1590. X}
  1591. X
  1592. X
  1593. X/*
  1594. X * NAME
  1595. X *    id_assign - assign a variable
  1596. X *
  1597. X * SYNOPSIS
  1598. X *    void id_assign(string_ty *name, id_class_ty class, ...);
  1599. X *
  1600. X * DESCRIPTION
  1601. X *    Id_assign is used to assign a value to a given variable.
  1602. X *
  1603. X * CAVEAT
  1604. X *    The name and value are copied by id_assign, so the user may
  1605. X *    modify or free them at a later date without affecting the
  1606. X *    variable.
  1607. X */
  1608. X
  1609. X/*VARARGS2*/
  1610. Xvoid
  1611. Xid_assign(name, class, arg)
  1612. X    string_ty    *name;
  1613. X    id_class_ty    class;
  1614. X    void        *arg;
  1615. X{
  1616. X    str_hash_ty    myhash;
  1617. X    str_hash_ty    index;
  1618. X    id        *p;
  1619. X
  1620. X    myhash = name->str_hash + (int)class;
  1621. X    index = myhash & hash_cutover_mask;
  1622. X    if (index < hash_split)
  1623. X        index = myhash & hash_cutover_split_mask;
  1624. X
  1625. X    for (p = hash_table[index]; p; p = p->id_next)
  1626. X    {
  1627. X        if (p->id_class == class && str_equal(name, p->id_name))
  1628. X        {
  1629. X            stomp(p);
  1630. X            assign(p, arg);
  1631. X            return;
  1632. X        }
  1633. X    }
  1634. X
  1635. X    p = (id *)mem_alloc_clear(size_by_class(class));
  1636. X    p->id_name = str_copy(name);
  1637. X    p->id_next = hash_table[index];
  1638. X    p->id_class = class;
  1639. X    p->id_hash = myhash;
  1640. X    hash_table[index] = p;
  1641. X    assign(p, arg);
  1642. X
  1643. X    hash_load++;
  1644. X    while (hash_load * 10 >= hash_modulus * 8)
  1645. X        split();
  1646. X}
  1647. X
  1648. X
  1649. X/*
  1650. X * NAME
  1651. X *    id_assign_push - assign a variable, remembering old value
  1652. X *
  1653. X * SYNOPSIS
  1654. X *    void id_assign_push(string_ty *name, id_class_ty class, ...);
  1655. X *
  1656. X * DESCRIPTION
  1657. X *    Id_assign is used to assign a value to a given variable.
  1658. X *
  1659. X * CAVEAT
  1660. X *    The name and value are copied by id_assign, so the user may
  1661. X *    modify or free them at a later date without affecting the
  1662. X *    variable.
  1663. X */
  1664. X
  1665. X/*VARARGS2*/
  1666. Xvoid
  1667. Xid_assign_push(name, class, arg)
  1668. X    string_ty    *name;
  1669. X    id_class_ty    class;
  1670. X    void        *arg;
  1671. X{
  1672. X    str_hash_ty    myhash;
  1673. X    str_hash_ty    index;
  1674. X    id        *p;
  1675. X
  1676. X    myhash = name->str_hash + (int)class;
  1677. X    index = myhash & hash_cutover_mask;
  1678. X    if (index < hash_split)
  1679. X        index = myhash & hash_cutover_split_mask;
  1680. X
  1681. X    p = (id *)mem_alloc_clear(size_by_class(class));
  1682. X    p->id_name = str_copy(name);
  1683. X    p->id_next = hash_table[index];
  1684. X    p->id_class = class;
  1685. X    p->id_hash = myhash;
  1686. X    hash_table[index] = p;
  1687. X    assign(p, arg);
  1688. X
  1689. X    hash_load++;
  1690. X    while (hash_load * 10 >= hash_modulus * 8)
  1691. X        split();
  1692. X}
  1693. X
  1694. X
  1695. X/*
  1696. X * NAME
  1697. X *    id_delete - delete a variable
  1698. X *
  1699. X * SYNOPSIS
  1700. X *    void id_delete(string_ty *name, id_class_ty class);
  1701. X *
  1702. X * DESCRIPTION
  1703. X *    Id_delete is used to delete variables.
  1704. X *
  1705. X * CAVEAT
  1706. X *    No complaint is made if the variable does not exist,
  1707. X *    since the user wanted it to not exist.
  1708. X */
  1709. X
  1710. Xvoid
  1711. Xid_delete(name, class)
  1712. X    string_ty    *name;
  1713. X    id_class_ty    class;
  1714. X{
  1715. X    str_hash_ty    myhash;
  1716. X    str_hash_ty    index;
  1717. X    id        **idpp;
  1718. X
  1719. X    myhash = name->str_hash + (int)class;
  1720. X    index = myhash & hash_cutover_mask;
  1721. X    if (index < hash_split)
  1722. X        index = myhash & hash_cutover_split_mask;
  1723. X
  1724. X    idpp = &hash_table[index];
  1725. X    for (;;)
  1726. X    {
  1727. X        id    *p;
  1728. X
  1729. X        p = *idpp;
  1730. X        if (!p)
  1731. X            break;
  1732. X        if (p->id_class == class && str_equal(name, p->id_name))
  1733. X        {
  1734. X            stomp(p);
  1735. X            str_free(p->id_name);
  1736. X            *idpp = p->id_next;
  1737. X            free(p);
  1738. X            hash_load--;
  1739. X            break;
  1740. X        }
  1741. X        idpp = &p->id_next;
  1742. X    }
  1743. X}
  1744. X
  1745. X
  1746. X/*
  1747. X * NAME
  1748. X *    id_dump - dump id table
  1749. X *
  1750. X * SYNOPSIS
  1751. X *    void id_dump(char *title, int mask);
  1752. X *
  1753. X * DESCRIPTION
  1754. X *    The id_dump function is used to dump the contents of the id table.
  1755. X *    The title will be used to indicate why the table was dumped.  The mask
  1756. X *    may be used to selectively dump the table, 0 means everything, bits
  1757. X *    correspond directly with ID_CLASS defines.
  1758. X *
  1759. X * RETURNS
  1760. X *    void
  1761. X *
  1762. X * CAVEAT
  1763. X *    This function is only available when symbol DEBUG is defined.
  1764. X */
  1765. X
  1766. X#ifdef DEBUG
  1767. X
  1768. Xvoid
  1769. Xid_dump(s, mask)
  1770. X    char        *s;
  1771. X    int        mask;
  1772. X{
  1773. X    int        j;
  1774. X    id        *p;
  1775. X
  1776. X    if (!mask)
  1777. X        mask = ~0;
  1778. X    error("id table %s = {", s);
  1779. X    for (j = 0; j < hash_modulus; ++j)
  1780. X    {
  1781. X        for (p = hash_table[j]; p; p = p->id_next)
  1782. X        {
  1783. X            if (mask & (1<< (int)p->id_class))
  1784. X            switch ((int)p->id_class)
  1785. X            {
  1786. X            default:
  1787. X                error
  1788. X                (
  1789. X                    "name = \"%s\", class = %d",
  1790. X                    p->id_name->str_text,
  1791. X                    p->id_class
  1792. X                );
  1793. X                break;
  1794. X
  1795. X            case ID_CLASS_VARIABLE:
  1796. X                {
  1797. X                    id_wlist    *ip;
  1798. X                    string_ty    *str;
  1799. X        
  1800. X                    ip = (id_wlist*)p;
  1801. X                    str = wl2str(&ip->id_value, 0, 32767);
  1802. X                    error
  1803. X                    (
  1804. X                    "name = \"%s\", class = %d, value = \"%s\"",
  1805. X                        p->id_name->str_text,
  1806. X                        p->id_class,
  1807. X                        str->str_text
  1808. X                    );
  1809. X                    str_free(str);
  1810. X                }
  1811. X                break;
  1812. X        
  1813. X            case ID_CLASS_ALREADY:
  1814. X            case ID_CLASS_FLAGS:
  1815. X            case ID_CLASS_HASH_KEYWORD:
  1816. X            case ID_CLASS_PARSE_KEYWORD:
  1817. X                {
  1818. X                    id_int        *ip;
  1819. X        
  1820. X                    ip = (id_int*)p;
  1821. X                    error
  1822. X                    (
  1823. X                    "name = \"%s\", class = %d, value = %d",
  1824. X                        p->id_name->str_text,
  1825. X                        p->id_class,
  1826. X                        ip->id_value
  1827. X                    );
  1828. X                }
  1829. X                break;
  1830. X        
  1831. X            case ID_CLASS_BUILTIN:
  1832. X                {
  1833. X                    id_bifp        *ip;
  1834. X        
  1835. X                    ip = (id_bifp*)p;
  1836. X                    error
  1837. X                    (
  1838. X                      "name = \"%s\", class = %d, value = %08X",
  1839. X                        p->id_name->str_text,
  1840. X                        p->id_class,
  1841. X                        ip->id_value
  1842. X                    );
  1843. X                }
  1844. X                break;
  1845. X        
  1846. X            case ID_CLASS_STAT:
  1847. X                {
  1848. X                    id_stat        *ip;
  1849. X        
  1850. X                    ip = (id_stat*)p;
  1851. X                    error
  1852. X                    (
  1853. X        "name = \"%s\", class = %d, value = {ino = %04X, mtime = %08X}",
  1854. X                        p->id_name->str_text,
  1855. X                        p->id_class,
  1856. X                        ip->id_value.st_ino,
  1857. X                        ip->id_value.st_mtime
  1858. X                    );
  1859. X                }
  1860. X                break;
  1861. X            }
  1862. X        }
  1863. X    }
  1864. X    error("}");
  1865. X}
  1866. X
  1867. X#endif
  1868. END_OF_FILE
  1869. if test 15314 -ne `wc -c <'cook/id.c'`; then
  1870.     echo shar: \"'cook/id.c'\" unpacked with wrong size!
  1871. fi
  1872. # end of 'cook/id.c'
  1873. fi
  1874. if test -f 'cook/match.c' -a "${1}" != "-c" ; then 
  1875.   echo shar: Will not clobber existing file \"'cook/match.c'\"
  1876. else
  1877. echo shar: Extracting \"'cook/match.c'\" \(13567 characters\)
  1878. sed "s/^X//" >'cook/match.c' <<'END_OF_FILE'
  1879. X/*
  1880. X *    cook - file construction tool
  1881. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  1882. X *    All rights reserved.
  1883. X *
  1884. X *    This program is free software; you can redistribute it and/or modify
  1885. X *    it under the terms of the GNU General Public License as published by
  1886. X *    the Free Software Foundation; either version 2 of the License, or
  1887. X *    (at your option) any later version.
  1888. X *
  1889. X *    This program is distributed in the hope that it will be useful,
  1890. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1891. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1892. X *    GNU General Public License for more details.
  1893. X *
  1894. X *    You should have received a copy of the GNU General Public License
  1895. X *    along with this program; if not, write to the Free Software
  1896. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1897. X *
  1898. X * MANIFEST: functions to perform recipe pattern matching
  1899. X *
  1900. X * This is in the inner loop, so it must perform well.
  1901. X * A free list of match structures is maintained to avoid malloc calls;
  1902. X * malloc is only called when this free list is empty.
  1903. X *
  1904. X * The tough part about designing a pattern matcher for something like cook is
  1905. X * that the patterns must be reversible.  That is, it must be possible to use
  1906. X * the same string both as a pattern to be matched against and as a template
  1907. X * for building a string once a pattern has matched.  Rather like the
  1908. X * difference between the left and right sides of an editor search-and-replace
  1909. X * command using the same description for both the search pattern and the
  1910. X * replace template.  This is why classic regular expressions have not been
  1911. X * used.  They tend to be slow to match, too.
  1912. X *
  1913. X * This matcher has eleven match "fields", referenced as % and %0 to %9.
  1914. X * The % character can be escaped as %%.  The % and %1 to %9 forms match any
  1915. X * character except '/'.  The %0 form matches all characters, but must be
  1916. X * either empty, or have whole path components, including the trailing '/' on
  1917. X * each component.  A few examples will make this clearer:
  1918. X *    "%.c" matches "fred.c" with %="fred"
  1919. X *    "%.c" failes to match "snot/fred.c"
  1920. X *    "%1/%2.c"matches "snot/fred.c" with %1="snot" and %2="fred"
  1921. X *    "%1/%2.c" fails to match "etc/boo/fred.c"
  1922. X *    "%0%5.c" matches "fred.c" with %0="" and %5="fred"
  1923. X *    "%0%6.c" matches "snot/fred.c" with %0="snot/" and %6="fred"
  1924. X *    "%0%7.c" matches "etc/boo/fred.c" with %0="etc/boo/" and %7="fred"
  1925. X *    "/usr/%1/%1%2/%3.%2%4" matches "/usr/man/man1/fred.1x" with %1="man",
  1926. X *        %2="1", %3="fred" and %4="x".
  1927. X * The %0 behaviour is designed to allow patterns to range over subtrees in a
  1928. X * controlled manner.  Note that the use of this sort of pattern in a recipe
  1929. X * will result in deeper seraches than the naive recipe designer would expect.
  1930. X */
  1931. X
  1932. X#include <stddef.h>
  1933. X#include <string.h>
  1934. X#include <stdlib.h>
  1935. X
  1936. X#include <main.h>
  1937. X#include <str.h>
  1938. X#include <match.h>
  1939. X#include <error.h>
  1940. X#include <mem.h>
  1941. X#include <trace.h>
  1942. X
  1943. X
  1944. X#define ABSENT_MARKER ((string_ty *)-1)
  1945. X
  1946. Xstatic match_ty *match_free_list;
  1947. Xstatic match_ty *stack;
  1948. X
  1949. X
  1950. X/*
  1951. X * NAME
  1952. X *    illegal_pattern - complain
  1953. X *
  1954. X * SYNOPSIS
  1955. X *    void illegal_pattern(char *s);
  1956. X *
  1957. X * DESCRIPTION
  1958. X *    The illegal_pattern function is used to complain about errors in
  1959. X *    pattern secifications.
  1960. X *
  1961. X * RETURNS
  1962. X *    void
  1963. X */
  1964. X
  1965. Xstatic void illegal_pattern _((char *, int));
  1966. X
  1967. Xstatic void
  1968. Xillegal_pattern(s, why)
  1969. X    char        *s;
  1970. X    int        why;
  1971. X{
  1972. X    if (why < 0)
  1973. X    {
  1974. X        fatal
  1975. X        (
  1976. X            "illegal position of '%c0' in \"%s\" pattern",
  1977. X            MATCH_CHAR,
  1978. X            s
  1979. X        );
  1980. X    }
  1981. X    if (why >= 10)
  1982. X        fatal("illegal use of '%c' in \"%s\" pattern", MATCH_CHAR, s);
  1983. X    fatal("illegal use of '%c%d' in \"%s\" pattern", MATCH_CHAR, why, s);
  1984. X}
  1985. X
  1986. X
  1987. X/*
  1988. X * NAME
  1989. X *    match_alloc - allocate match structure
  1990. X *
  1991. X * SYNOPSIS
  1992. X *    match_ty *match_alloc(void);
  1993. X *
  1994. X * DESCRIPTION
  1995. X *    The match_alloc function is used to allocate a match structure.
  1996. X *    The returned structure will be all zeros.
  1997. X *
  1998. X * RETURNS
  1999. X *    match_ty * - a pointer to the match structure in dynamic memory
  2000. X *
  2001. X * CAVEAT
  2002. X *    When finished with it should be disposed of by calling the match_free
  2003. X *    function.
  2004. X */
  2005. X
  2006. Xstatic match_ty *match_alloc _((void));
  2007. X
  2008. Xstatic match_ty *
  2009. Xmatch_alloc()
  2010. X{
  2011. X    match_ty    *result;
  2012. X    int        j;
  2013. X
  2014. X    if (match_free_list)
  2015. X    {
  2016. X        result = match_free_list;
  2017. X        match_free_list = result->next;
  2018. X    }
  2019. X    else
  2020. X        result = (match_ty *)mem_alloc(sizeof(match_ty));
  2021. X    for (j = 0; j < SIZEOF(result->fill); ++j)
  2022. X        result->fill[j] = 0;
  2023. X    result->next = 0;
  2024. X    return result;
  2025. X}
  2026. X
  2027. X
  2028. X/*
  2029. X * NAME
  2030. X *    match_free - dispose of match structure
  2031. X *
  2032. X * SYNOPSIS
  2033. X *    void match_free(match_ty *);
  2034. X *
  2035. X * DESCRIPTION
  2036. X *    The match_free function is used to dispose of a match structure
  2037. X *    allocated by the match_alloc function.
  2038. X *
  2039. X * RETURNS
  2040. X *    void
  2041. X */
  2042. X
  2043. Xvoid
  2044. Xmatch_free(field)
  2045. X    match_ty    *field;
  2046. X{
  2047. X    int        j;
  2048. X
  2049. X    trace(("match_free(field = %08X)\n{\n"/*}*/, field));
  2050. X    for (j = 0; j < SIZEOF(field->fill); ++j)
  2051. X    {
  2052. X        if (field->fill[j])
  2053. X        {
  2054. X            str_free(field->fill[j]);
  2055. X            field->fill[j] = 0;
  2056. X        }
  2057. X    }
  2058. X    field->next = match_free_list;
  2059. X    match_free_list = field;
  2060. X    trace((/*{*/"}\n"));
  2061. X}
  2062. X
  2063. X
  2064. X/*
  2065. X * NAME
  2066. X *    matcher - match pattern to string
  2067. X *
  2068. X * SYNOPSIS
  2069. X *    int matcher(char *original_patn, char *patn, char *str, match_ty *field);
  2070. X *
  2071. X * DESCRIPTION
  2072. X *    The matcher function is used to match up a pattern with a string,
  2073. X *    filling in the fields as it goes.
  2074. X *
  2075. X * RETURNS
  2076. X *    int: zero if does not match, nonzero if does match.
  2077. X *
  2078. X * CAVEAT
  2079. X *    The field structure is not allocated here.
  2080. X */
  2081. X
  2082. Xstatic int matcher _((char *, char *, char *, match_ty *));
  2083. X
  2084. Xstatic int
  2085. Xmatcher(op, p, s, field)
  2086. X    char        *op;    /* original pattern */
  2087. X    char        *p;
  2088. X    char        *s;
  2089. X    match_ty    *field;
  2090. X{
  2091. X    size_t        index;
  2092. X    string_ty    *sp;
  2093. X    int        result;
  2094. X
  2095. X    trace(("matcher(op = %08lX, p = %08lX, s = %08lX, field = %08X)\n{\n"/*}*/, op, p, s, field));
  2096. X    trace_string(op);
  2097. X    trace_string(p);
  2098. X    trace_string(s);
  2099. X    for (;;)
  2100. X    {
  2101. X        switch (*p)
  2102. X        {
  2103. X        case 0:
  2104. X            result = !*s;
  2105. X            goto ret;
  2106. X
  2107. X        case MATCH_CHAR:
  2108. X            if (p[1] == MATCH_CHAR)
  2109. X            {
  2110. X                if (*s++ != MATCH_CHAR)
  2111. X                {
  2112. X                    result = 0;
  2113. X                    goto ret;
  2114. X                }
  2115. X                p += 2;
  2116. X                break;
  2117. X            }
  2118. X            if (p[1] >= '0' && p[1] <= '9')
  2119. X            {
  2120. X                index = p[1] - '0';
  2121. X                p += 2;
  2122. X            }
  2123. X            else
  2124. X            {
  2125. X                index = 10;
  2126. X                ++p;
  2127. X            }
  2128. X            if
  2129. X            (
  2130. X                !index
  2131. X            &&
  2132. X                (
  2133. X                    (p - 2 != op && p[-3] != '/')
  2134. X                ||
  2135. X                    (!*p || *p == '/')
  2136. X                )
  2137. X            )
  2138. X                illegal_pattern(op, -1);
  2139. X            sp = field->fill[index];
  2140. X            if (sp)
  2141. X            {
  2142. X                char    *q;
  2143. X
  2144. X                q = sp->str_text;
  2145. X                while (*q)
  2146. X                {
  2147. X                    if (*q++ != *s++)
  2148. X                    {
  2149. X                        result = 0;
  2150. X                        goto ret;
  2151. X                    }
  2152. X                }
  2153. X            }
  2154. X            else
  2155. X            {
  2156. X                char *q;
  2157. X
  2158. X                if (index)
  2159. X                {
  2160. X                    q = strchr(s, '/');
  2161. X                    if (!q)
  2162. X                        q = s + strlen(s);
  2163. X                    if (q == s)
  2164. X                    {
  2165. X                        result = 0;
  2166. X                        goto ret;
  2167. X                    }
  2168. X                }
  2169. X                else
  2170. X                {
  2171. X                    q = strrchr(s, '/');
  2172. X                    if (!q || *s == '/')
  2173. X                        q = s;
  2174. X                    else
  2175. X                        q++;
  2176. X                }
  2177. X                while (q >= s)
  2178. X                {
  2179. X                    field->fill[index] = str_n_from_c(s, q - s);
  2180. X                    trace_long_unsigned(index);
  2181. X                    trace_string(field->fill[index]->str_text);
  2182. X                    if (matcher(op, p, q, field))
  2183. X                    {
  2184. X                        result = 1;
  2185. X                        goto ret;
  2186. X                    }
  2187. X                    str_free(field->fill[index]);
  2188. X                    field->fill[index] = 0;
  2189. X                    --q;
  2190. X                    if (!index)
  2191. X                        while (q >= s)
  2192. X                        {
  2193. X                            if (q > s && q[-1] == '/')
  2194. X                                break;
  2195. X                            --q;
  2196. X                        }
  2197. X                }
  2198. X                result = 0;
  2199. X                goto ret;
  2200. X            }
  2201. X            break;
  2202. X
  2203. X        default:
  2204. X            if (*p++ != *s++)
  2205. X            {
  2206. X                result = 0;
  2207. X                goto ret;
  2208. X            }
  2209. X            break;
  2210. X        }
  2211. X    }
  2212. Xret:
  2213. X    trace(("return %d;\n", result));
  2214. X    trace((/*{*/"}\n"));
  2215. X    return result;
  2216. X}
  2217. X
  2218. X
  2219. X/*
  2220. X * NAME
  2221. X *    match - attempt to
  2222. X *
  2223. X * SYNOPSIS
  2224. X *    match_ty *match(string_ty *pattern, string_ty *string);
  2225. X *
  2226. X * DESCRIPTION
  2227. X *    The match function is used to match a pattern with a string.
  2228. X *    The matching fields are filled in in the returned structure.
  2229. X *
  2230. X * RETURNS
  2231. X *    match_ty *: a pointer to a match structure in dynamic memory with the
  2232. X *    match fields set as appropriate.  A NULL pointer is returned if the
  2233. X *    string does not match the pattern.
  2234. X *
  2235. X * CAVEAT
  2236. X *    The match structure should be releaseed by calling match_free.,
  2237. X */
  2238. X
  2239. Xmatch_ty *
  2240. Xmatch(pattern, string)
  2241. X    string_ty    *pattern;
  2242. X    string_ty    *string;
  2243. X{
  2244. X    match_ty    *field;
  2245. X
  2246. X    trace(("match(pattern = %08lX, string = %08lX)\n{\n"/*}*/, pattern, string));
  2247. X    trace_string(pattern->str_text);
  2248. X    trace_string(string->str_text);
  2249. X    field = match_alloc();
  2250. X    if (!matcher(pattern->str_text, pattern->str_text, string->str_text, field))
  2251. X    {
  2252. X        match_free(field);
  2253. X        field = 0;
  2254. X    }
  2255. X    trace(("retrurn %08lX;\n", field));
  2256. X    trace((/*{*/"}\n"));
  2257. X    return field;
  2258. X}
  2259. X
  2260. X
  2261. X/*
  2262. X * NAME
  2263. X *    reconstruct - make string from pattern
  2264. X *
  2265. X * SYNOPSIS
  2266. X *    string_ty *reconstruct(string_ty *pattern, match_ty *field);
  2267. X *
  2268. X * DESCRIPTION
  2269. X *    The reconstruct function is used to rebuild a string from a replacement
  2270. X *    pattern and the match field values.
  2271. X *
  2272. X * RETURNS
  2273. X *    string_ty *
  2274. X *
  2275. X * CAVEAT
  2276. X *    It is a fatal error for the pattern to reference fields not set by the
  2277. X *    pattern match which created the fields match structure.
  2278. X */
  2279. X
  2280. Xstring_ty *
  2281. Xreconstruct(pattern, field)
  2282. X    string_ty    *pattern;
  2283. X    match_ty    *field;
  2284. X{
  2285. X    static char    *tmp;
  2286. X    static size_t    tmplen;
  2287. X    size_t        length;
  2288. X    char        *p;
  2289. X    string_ty    *s;
  2290. X    char        *pos;
  2291. X    int        index;
  2292. X
  2293. X    trace(("reconstruct(pattern = %08lX, field = %08X)\n{\n"/*}*/, pattern, field));
  2294. X    trace_string(pattern->str_text);
  2295. X    length = 0;
  2296. X    for (p = pattern->str_text; *p; ++p)
  2297. X    {
  2298. X        if (*p == MATCH_CHAR)
  2299. X        {
  2300. X            if (p[1] == MATCH_CHAR)
  2301. X            {
  2302. X                ++length;
  2303. X                ++p;
  2304. X                continue;
  2305. X            }
  2306. X            if (p[1] >= '0' && p[1] <= '9')
  2307. X            {
  2308. X                index = p[1] - '0';
  2309. X                ++p;
  2310. X            }
  2311. X            else
  2312. X                index = 10;
  2313. X            s = field->fill[index];
  2314. X            if (!s)
  2315. X                illegal_pattern(pattern->str_text, index);
  2316. X            length += s->str_length;
  2317. X        }
  2318. X        else
  2319. X            ++length;
  2320. X    }
  2321. X
  2322. X    if (!tmp)
  2323. X    {
  2324. X        tmplen = length;
  2325. X        if (tmplen < 16)
  2326. X            tmplen = 16;
  2327. X        tmp = mem_alloc(tmplen);
  2328. X    }
  2329. X    else
  2330. X    {
  2331. X        if (tmplen < length)
  2332. X        {
  2333. X            tmplen = length;
  2334. X            mem_change_size(&tmp, tmplen);
  2335. X        }
  2336. X    }
  2337. X
  2338. X    pos = tmp;
  2339. X    for (p = pattern->str_text; *p; ++p)
  2340. X    {
  2341. X        if (*p == MATCH_CHAR)
  2342. X        {
  2343. X            if (p[1] == MATCH_CHAR)
  2344. X            {
  2345. X                *pos++ = MATCH_CHAR;
  2346. X                ++p;
  2347. X                continue;
  2348. X            }
  2349. X            if (p[1] >= '0' && p[1] <= '9')
  2350. X            {
  2351. X                index = p[1] - '0';
  2352. X                ++p;
  2353. X            }
  2354. X            else
  2355. X                index = 10;
  2356. X            s = field->fill[index];
  2357. X            memcpy(pos, s->str_text, s->str_length);
  2358. X            pos += s->str_length;
  2359. X        }
  2360. X        else
  2361. X            *pos++ = *p;
  2362. X    }
  2363. X
  2364. X    s = str_n_from_c(tmp, length);
  2365. X    trace_string(s->str_text);
  2366. X    trace(("return %08lX;\n", s));
  2367. X    trace((/*{*/"}\n"));
  2368. X    return s;
  2369. X}
  2370. X
  2371. X
  2372. X/*
  2373. X * NAME
  2374. X *    match_push - patch match fields
  2375. X *
  2376. X * SYNOPSIS
  2377. X *    void match_push(match_ty *field);
  2378. X *
  2379. X * DESCRIPTION
  2380. X *    The match_push function is used to push a pattern onto the stack of
  2381. X *    match fields.  A NULL pointer may be pushed.  This mechanism is used by
  2382. X *    the chef (cook.c) to indicate implicit and explicit recipe replacements.
  2383. X *
  2384. X * RETURNS
  2385. X *    void
  2386. X */
  2387. X
  2388. Xvoid
  2389. Xmatch_push(field)
  2390. X    match_ty    *field;
  2391. X{
  2392. X    trace(("match_push(field = %08X)\n{\n"/*}*/, field));
  2393. X    if (!field)
  2394. X    {
  2395. X        field = match_alloc();
  2396. X        field->fill[0] = ABSENT_MARKER;
  2397. X    }
  2398. X    field->next = stack;
  2399. X    stack= field;
  2400. X    trace((/*{*/"}\n"));
  2401. X}
  2402. X
  2403. X
  2404. X/*
  2405. X * NAME
  2406. X *    match_top - top of match stack
  2407. X *
  2408. X * SYNOPSIS
  2409. X *    match_ty *match_top(void);
  2410. X *
  2411. X * DESCRIPTION
  2412. X *    The match function is used to indicate the top of the match stack.
  2413. X *
  2414. X * RETURNS
  2415. X *    match_ty * - a pointer to a match strcuture, or NULL if the stack is
  2416. X *    empty, or a NULL was pashed to mak an exlpicit recipe.
  2417. X */
  2418. X
  2419. Xmatch_ty *
  2420. Xmatch_top()
  2421. X{
  2422. X    match_ty    *result;
  2423. X
  2424. X    if (stack && stack->fill[0] == ABSENT_MARKER)
  2425. X        result = 0;
  2426. X    else
  2427. X        result = stack;
  2428. X    return result;
  2429. X}
  2430. X
  2431. X
  2432. X/*
  2433. X * NAME
  2434. X *    match_pop - shorten stack
  2435. X *
  2436. X * SYNOPSIS
  2437. X *    match_ty *match_pop(void);
  2438. X *
  2439. X * DESCRIPTION
  2440. X *    The match_pop function is used to pop a match structure from the match
  2441. X *    stack.
  2442. X *
  2443. X * RETURNS
  2444. X *    match_ty * - a pointer to a match strcuture, or NULL if the stack is
  2445. X *    empty, or a NULL was pashed to mak an exlpicit recipe.
  2446. X *
  2447. X * CAVEAT
  2448. X *    It is an error for the stack to be empty.
  2449. X */
  2450. X
  2451. Xmatch_ty *
  2452. Xmatch_pop()
  2453. X{
  2454. X    match_ty    *field;
  2455. X
  2456. X    trace(("match_pop()\n{\n"/*}*/));
  2457. X    assert(stack);
  2458. X    field = stack;
  2459. X    stack = stack->next;
  2460. X    if (field->fill[0] == ABSENT_MARKER)
  2461. X    {
  2462. X        free(field);
  2463. X        field = 0;
  2464. X    }
  2465. X    trace(("return %08X;\n", field));
  2466. X    trace((/*{*/"}\n"));
  2467. X    return field;
  2468. X}
  2469. X
  2470. X
  2471. X/*
  2472. X * NAME
  2473. X *    wl_match - find a pattern in a word list
  2474. X *
  2475. X * SYNOPSIS
  2476. X *    match_ty *wl_match(wlist *pattern, string_ty *target);
  2477. X *
  2478. X * DESCRIPTION
  2479. X *    Wl_match is used to determine whether any one of the words in
  2480. X *    the wordlist (wlp) match the pattern given.
  2481. X *
  2482. X * RETURNS
  2483. X *    A zero is returned if not one of the words matches the pattern;
  2484. X *    otherwise a pointer to a "match structure" is returned,
  2485. X *    in a similar fashion to match().
  2486. X *
  2487. X * CAVEAT
  2488. X *    The information returned resides in dynamic memory.
  2489. X *    It is the responsibility of the
  2490. X *    caller to ensure that it is freed when it is finished with,
  2491. X *    by a call to match_free();
  2492. X */
  2493. X
  2494. Xmatch_ty *
  2495. Xwl_match(pattern, target)
  2496. X    wlist        *pattern;
  2497. X    string_ty    *target;
  2498. X{
  2499. X    int        j;
  2500. X    match_ty    *retval;
  2501. X
  2502. X    for (j = 0; j < pattern->wl_nwords; j++)
  2503. X    {
  2504. X        retval = match(pattern->wl_word[j], target);
  2505. X        if (retval)
  2506. X            return retval;
  2507. X    }
  2508. X    return 0;
  2509. X}
  2510. X
  2511. X
  2512. X/*
  2513. X * NAME
  2514. X *    wl_reconstruct - reconstruct a word list
  2515. X *
  2516. X * SYNOPSIS
  2517. X *    void wl_reconstruct(wlist *to, wlist *from, match_ty *field)
  2518. X *
  2519. X * DESCRIPTION
  2520. X *    Wl_reconstruct is used to reconstruct an entire word list,
  2521. X *    sort of the convers of wl_match().
  2522. X *
  2523. X * RETURNS
  2524. X *    'To' is a word list of reconstructed strings.
  2525. X *
  2526. X * CAVEAT
  2527. X *    It is the responsibility of the caller to ensire that the
  2528. X *    reconstructed word list in 'to' is freed when finished with,
  2529. X *    by a call to wl_free().
  2530. X */
  2531. X
  2532. Xvoid
  2533. Xwl_reconstruct(to, from, field)
  2534. X    wlist        *to;
  2535. X    wlist        *from;
  2536. X    match_ty    *field;
  2537. X{
  2538. X    int        j;
  2539. X
  2540. X    wl_zero(to);
  2541. X    for (j = 0; j < from->wl_nwords; j++)
  2542. X    {
  2543. X        string_ty *s;
  2544. X
  2545. X        s = reconstruct(from->wl_word[j], field);
  2546. X        wl_append(to, s);
  2547. X        str_free(s);
  2548. X    }
  2549. X}
  2550. END_OF_FILE
  2551. if test 13567 -ne `wc -c <'cook/match.c'`; then
  2552.     echo shar: \"'cook/match.c'\" unpacked with wrong size!
  2553. fi
  2554. # end of 'cook/match.c'
  2555. fi
  2556. if test -f 'cook/stmt.c' -a "${1}" != "-c" ; then 
  2557.   echo shar: Will not clobber existing file \"'cook/stmt.c'\"
  2558. else
  2559. echo shar: Extracting \"'cook/stmt.c'\" \(13734 characters\)
  2560. sed "s/^X//" >'cook/stmt.c' <<'END_OF_FILE'
  2561. X/*
  2562. X *    cook - file construction tool
  2563. X *    Copyright (C) 1990, 1991, 1992, 1993 Peter Miller.
  2564. X *    All rights reserved.
  2565. X *
  2566. X *    This program is free software; you can redistribute it and/or modify
  2567. X *    it under the terms of the GNU General Public License as published by
  2568. X *    the Free Software Foundation; either version 2 of the License, or
  2569. X *    (at your option) any later version.
  2570. X *
  2571. X *    This program is distributed in the hope that it will be useful,
  2572. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2573. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2574. X *    GNU General Public License for more details.
  2575. X *
  2576. X *    You should have received a copy of the GNU General Public License
  2577. X *    along with this program; if not, write to the Free Software
  2578. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2579. X *
  2580. X * MANIFEST: functions to manage statement trees
  2581. X *
  2582. X * This file contains the functions for manipulating statement trees,
  2583. X * allocating, interpreting and releasing.
  2584. X */
  2585. X
  2586. X#include <stddef.h>
  2587. X#include <string.h>
  2588. X#include <time.h>
  2589. X
  2590. X#include <cook.h>
  2591. X#include <env.h>
  2592. X#include <error.h>
  2593. X#include <expr.h>
  2594. X#include <id.h>
  2595. X#include <main.h>
  2596. X#include <match.h>
  2597. X#include <mem.h>
  2598. X#include <option.h>
  2599. X#include <os.h>
  2600. X#include <stmt.h>
  2601. X#include <trace.h>
  2602. X#include <word.h>
  2603. X
  2604. X
  2605. X/*
  2606. X *  NAME
  2607. X *    stmt_alloc - allocate a statement structure
  2608. X *
  2609. X *  SYNOPSIS
  2610. X *    stmt *stmt_alloc(void);
  2611. X *
  2612. X *  DESCRIPTION
  2613. X *    Allocates a statement structure, initializing it to zeroes.
  2614. X *
  2615. X *  RETURNS
  2616. X *    A pointer to the dynamically allocated space is returned.
  2617. X *
  2618. X *  CAVEAT
  2619. X *    It is the responsibility of the caller to ensure that the space is
  2620. X *    freed when finished with, by a call to stmt_free().
  2621. X */
  2622. X
  2623. Xstmt *
  2624. Xstmt_alloc()
  2625. X{
  2626. X    stmt        *sp;
  2627. X
  2628. X    trace(("stmt_alloc()\n{\n"/*}*/));
  2629. X    sp = (stmt *)mem_alloc_clear(sizeof(stmt));
  2630. X    sp->s_references = 1;
  2631. X    trace(("return %08lX;\n", sp));
  2632. X    trace((/*{*/"}\n"));
  2633. X    return sp;
  2634. X}
  2635. X
  2636. X
  2637. X/*
  2638. X *  NAME
  2639. X *      stmt_copy - copy statement tree
  2640. X *
  2641. X *  SYNOPSIS
  2642. X *      stmt *stmt_copy(stmt *);
  2643. X *
  2644. X *  DESCRIPTION
  2645. X *      The stmt_copy function is used to make a copy of a statement tree.
  2646. X *
  2647. X *  RETURNS
  2648. X *      stmt* - pointer to the root of the copied statement tree in dynamic
  2649. X *      memory.
  2650. X *
  2651. X *  CAVEAT
  2652. X *      Use the stmt_free function to release the tree when finished with.
  2653. X */
  2654. X
  2655. Xstmt *
  2656. Xstmt_copy(sp)
  2657. X    stmt        *sp;
  2658. X{
  2659. X    trace(("stmt_copy(sp = %08X)\n{\n"/*}*/, sp));
  2660. X    sp->s_references++;
  2661. X    trace(("return %08X;\n", sp));
  2662. X    trace((/*{*/"}\n"));
  2663. X    return sp;
  2664. X}
  2665. X
  2666. X
  2667. X/*
  2668. X *  NAME
  2669. X *    stmt_free - free a statement tree
  2670. X *
  2671. X *  SYNOPSIS
  2672. X *    void stmt_free(stmt *sp);
  2673. X *
  2674. X *  DESCRIPTION
  2675. X *    Frees a statement structure after it has been executed.
  2676. X *
  2677. X *  CAVEAT
  2678. X *    It is assumed that the statement tree is in dynamic memory.
  2679. X */
  2680. X
  2681. Xvoid
  2682. Xstmt_free(sp)
  2683. X    stmt        *sp;
  2684. X{
  2685. X    trace(("stmt_free(sp = %08X)\n{\n"/*}*/, sp));
  2686. X    assert(sp);
  2687. X    sp->s_references--;
  2688. X    if (sp->s_references > 0)
  2689. X        goto ret;
  2690. X    assert(sp->s_references == 0);
  2691. X    switch ((int)sp->s_op)
  2692. X    {
  2693. X    default:
  2694. X        fatal("bad statement selector %d (bug)", sp->s_op);
  2695. X
  2696. X    case OP_ASSIGN:
  2697. X        el_free(&sp->s_assign.a_name);
  2698. X        el_free(&sp->s_assign.a_value);
  2699. X        break;
  2700. X
  2701. X    case OP_COMMAND:
  2702. X        el_free(&sp->s_cmd.c_args);
  2703. X        if (sp->s_cmd.c_input)
  2704. X            expr_free(sp->s_cmd.c_input);
  2705. X        break;
  2706. X
  2707. X    case OP_TOUCH:
  2708. X    case OP_UNSETENV:
  2709. X        el_free(&sp->s_cmd.c_args);
  2710. X        break;
  2711. X
  2712. X    case OP_COMPOUND:
  2713. X        sl_free(&sp->s_list);
  2714. X        break;
  2715. X
  2716. X    case OP_SET:
  2717. X    case OP_LOOPSTOP:
  2718. X    case OP_NOP:
  2719. X    case OP_FAIL:
  2720. X    case OP_FAIL_DK:
  2721. X        break;
  2722. X
  2723. X    case OP_IF:
  2724. X        expr_free(sp->s_if.sif_cond);
  2725. X        stmt_free(sp->s_if.sif_true);
  2726. X        stmt_free(sp->s_if.sif_false);
  2727. X        break;
  2728. X
  2729. X    case OP_LOOP:
  2730. X        stmt_free(sp->s_loop);
  2731. X        break;
  2732. X
  2733. X    case OP_RECIPE:
  2734. X        el_free(&sp->s_recipe.sr_target);
  2735. X        el_free(&sp->s_recipe.sr_need);
  2736. X        el_free(&sp->s_recipe.sr_need2);
  2737. X        if (sp->s_recipe.sr_precondition)
  2738. X            expr_free(sp->s_recipe.sr_precondition);
  2739. X        if (sp->s_recipe.sr_action)
  2740. X            stmt_free(sp->s_recipe.sr_action);
  2741. X        if (sp->s_recipe.sr_use_action)
  2742. X            stmt_free(sp->s_recipe.sr_use_action);
  2743. X        str_free(sp->s_recipe.sr_position.pos_name);
  2744. X        break;
  2745. X    }
  2746. X    mem_free((char *)sp);
  2747. Xret:
  2748. X    trace((/*{*/"}\n"));
  2749. X}
  2750. X
  2751. X
  2752. X/*
  2753. X *  NAME
  2754. X *    stmt_eval - evaluate a statement
  2755. X *
  2756. X *  SYNOPSIS
  2757. X *    int stmt_eval(stmt *sp);
  2758. X *
  2759. X *  DESCRIPTION
  2760. X *    Stmt_eval is used to evaluate a statement tree.
  2761. X *    It performs the actions so implied.
  2762. X *
  2763. X *  RETURNS
  2764. X *    The value returned indicates why the statement evaluation terminated.
  2765. X *        STMT_OK    normal termination, success
  2766. X *        STMT_LSTOP    a loopstop statement was encountered
  2767. X *        STMT_ERROR    an execution error in a command was encountered
  2768. X *    There is also the posibility of internal subroutines;
  2769. X *    If an when this happens, an additional STMT_RET value could be returned.
  2770. X *
  2771. X *  CAVEAT
  2772. X *    The explicit and implicit recipes need to copy the statement
  2773. X *    bound to them.
  2774. X *
  2775. X *    The explicit and implicit recipes need to overwrite recipes with
  2776. X *    identical target and prerequisite lists. The best place to do this
  2777. X *    is in rl_append().
  2778. X */
  2779. X
  2780. Xint
  2781. Xstmt_eval(sp)
  2782. X    stmt        *sp;
  2783. X{
  2784. X    int        status;
  2785. X
  2786. X    trace(("stmt_eval(sp = %08X)\n{\n"/*}*/, sp));
  2787. X    assert(sp);
  2788. X    if (desist)
  2789. X    {
  2790. X        status = STMT_ERROR;
  2791. X        goto ret;
  2792. X    }
  2793. X    status = STMT_OK;
  2794. X    switch ((int)sp->s_op)
  2795. X    {
  2796. X    default:
  2797. X        error("bad statement selector %d (bug)", sp->s_op);
  2798. X        option_set_errors();
  2799. X        status = STMT_ERROR;
  2800. X        break;
  2801. X
  2802. X    case OP_ASSIGN:
  2803. X        {
  2804. X            wlist        name;
  2805. X            wlist        value;
  2806. X            static string_ty    *setenv_word;
  2807. X            static string_ty    *mtime_word;
  2808. X
  2809. X            /*
  2810. X             * The grammar has the assignment as an expression list.
  2811. X             * Evaluate the expression list into a word list.
  2812. X             * This word list is the value to assign.
  2813. X             */
  2814. X            if (!setenv_word)
  2815. X                setenv_word = str_from_c("setenv");
  2816. X            if (!mtime_word)
  2817. X                mtime_word = str_from_c("mtime");
  2818. X            wl_zero(&name);
  2819. X            if (el2wl(&name, &sp->s_assign.a_name))
  2820. X            {
  2821. X                status = STMT_ERROR;
  2822. X                break;
  2823. X            }
  2824. X            switch (name.wl_nwords)
  2825. X            {
  2826. X            case 0:
  2827. X                error("lefthand side of assignment is empty");
  2828. X                option_set_errors();
  2829. X                status = STMT_ERROR;
  2830. X                break;
  2831. X
  2832. X            case 1:
  2833. X                if (el2wl(&value, &sp->s_assign.a_value))
  2834. X                {
  2835. X                    status = STMT_ERROR;
  2836. X                    break;
  2837. X                }
  2838. X                id_assign
  2839. X                (
  2840. X                    name.wl_word[0],
  2841. X                    ID_CLASS_VARIABLE,
  2842. X                    &value
  2843. X                );
  2844. X                wl_free(&value);
  2845. X                break;
  2846. X
  2847. X            case 2:
  2848. X                if (str_equal(name.wl_word[0], setenv_word))
  2849. X                {
  2850. X                    string_ty *s;
  2851. X
  2852. X                    if (el2wl(&value, &sp->s_assign.a_value))
  2853. X                    {
  2854. X                        status = STMT_ERROR;
  2855. X                        break;
  2856. X                    }
  2857. X                    s = wl2str(&value, 0, 32767);
  2858. X                    wl_free(&value);
  2859. X                    env_set
  2860. X                    (
  2861. X                        name.wl_word[1]->str_text,
  2862. X                        s->str_text
  2863. X                    );
  2864. X                    str_free(s);
  2865. X                    break;
  2866. X                }
  2867. X#if 0
  2868. X                if (str_equal(name.wl_word[0], mtime_word))
  2869. X                {
  2870. X                    mtime_pattern
  2871. X                    (
  2872. X                        name.wl_word[1],
  2873. X                        &sp->s_assign.a_value
  2874. X                    );
  2875. X                    break;
  2876. X                }
  2877. X#endif
  2878. X                /* fall through... */
  2879. X
  2880. X            default:
  2881. X                error
  2882. X                (
  2883. X                 "lefthand side of assignment is more than one word"
  2884. X                );
  2885. X                option_set_errors();
  2886. X                status = STMT_ERROR;
  2887. X                break;
  2888. X            }
  2889. X            wl_free(&name);
  2890. X        }
  2891. X        break;
  2892. X
  2893. X    case OP_UNSETENV:
  2894. X        {
  2895. X            wlist        wl;
  2896. X            int        j;
  2897. X
  2898. X            wl_zero(&wl);
  2899. X            if (el2wl(&wl, &sp->s_cmd.c_args))
  2900. X            {
  2901. X                status = STMT_ERROR;
  2902. X                break;
  2903. X            }
  2904. X            if (!wl.wl_nwords)
  2905. X            {
  2906. X                error("unsetenv was given no words");
  2907. X                option_set_errors();
  2908. X                status = STMT_ERROR;
  2909. X            }
  2910. X            for (j = 0; j < wl.wl_nwords; ++j)
  2911. X                env_unset(wl.wl_word[j]->str_text);
  2912. X            wl_free(&wl);
  2913. X        }
  2914. X        break;
  2915. X
  2916. X    case OP_COMMAND:
  2917. X        {
  2918. X            wlist    wl;
  2919. X            int        metering;
  2920. X
  2921. X            /*
  2922. X             * The grammar has the command as an expression list.
  2923. X             * Evaluate the expression list into a word list.
  2924. X             * This word list is the command to execute.
  2925. X             */
  2926. X            if (el2wl(&wl, &sp->s_cmd.c_args))
  2927. X            {
  2928. X                status = STMT_ERROR;
  2929. X                break;
  2930. X            }
  2931. X            cook_flags(sp->s_cmd.c_flags, OPTION_LEVEL_EXECUTE);
  2932. X            if (!option_test(OPTION_SILENT))
  2933. X            {
  2934. X                string_ty *cp;
  2935. X
  2936. X                /*
  2937. X                 * If the command has not been silenced,
  2938. X                 * form it into a string and echo it.
  2939. X                 */
  2940. X                cp = wl2str(&wl, 0, 32767);
  2941. X                error("%s", cp->str_text);
  2942. X                str_free(cp);
  2943. X                metering = option_test(OPTION_METER);
  2944. X            }
  2945. X            else
  2946. X            {
  2947. X                /* no metering if silent */
  2948. X                metering = 0;
  2949. X            }
  2950. X            if (option_test(OPTION_ACTION))
  2951. X            {
  2952. X                string_ty *s;
  2953. X
  2954. X                if (sp->s_cmd.c_input)
  2955. X                {
  2956. X                    wlist     input;
  2957. X
  2958. X                    wl_zero(&input);
  2959. X                    if (expr_eval(&input, sp->s_cmd.c_input))
  2960. X                    {
  2961. X                        status = STMT_ERROR;
  2962. X                        break;
  2963. X                    }
  2964. X                    s = wl2str(&input, 0, 32767);
  2965. X                    wl_free(&input);
  2966. X                }
  2967. X                else
  2968. X                    s = 0;
  2969. X                if (metering)
  2970. X                    os_meter_begin();
  2971. X                switch (os_execute(&wl, s))
  2972. X                {
  2973. X                case -1:
  2974. X                    status = STMT_ERROR;
  2975. X                    break;
  2976. X
  2977. X                case 0:
  2978. X                    break;
  2979. X
  2980. X                default:
  2981. X                    if (!option_test(OPTION_ERROK))
  2982. X                        status = STMT_ERROR;
  2983. X                    break;
  2984. X                }
  2985. X                if (metering)
  2986. X                    os_meter_end();
  2987. X                if (s)
  2988. X                    str_free(s);
  2989. X            }
  2990. X            if (option_test(OPTION_INVALIDATE_STAT_CACHE))
  2991. X            {
  2992. X                int        j;
  2993. X
  2994. X                for (j = 0; j < wl.wl_nwords; ++j)
  2995. X                    if (os_clear_stat(wl.wl_word[j]))
  2996. X                        status = STMT_ERROR;
  2997. X            }
  2998. X            wl_free(&wl);
  2999. X            option_undo_level(OPTION_LEVEL_EXECUTE);
  3000. X        }
  3001. X        break;
  3002. X
  3003. X    case OP_SET:
  3004. X        cook_flags(sp->s_cmd.c_flags, OPTION_LEVEL_COOKBOOK);
  3005. X        break;
  3006. X
  3007. X    case OP_FAIL:
  3008. X        status = STMT_ERROR;
  3009. X        break;
  3010. X
  3011. X    case OP_FAIL_DK:
  3012. X        status = STMT_BACKTRACK;
  3013. X        break;
  3014. X
  3015. X    case OP_COMPOUND:
  3016. X        {
  3017. X            int        j;
  3018. X
  3019. X            for (j = 0; j < sp->s_list.sl_nstmts; j++)
  3020. X            {
  3021. X                status = stmt_eval(sp->s_list.sl_stmt[j]);
  3022. X                if (status != STMT_OK)
  3023. X                    break;
  3024. X            }
  3025. X        }
  3026. X        break;
  3027. X
  3028. X    case OP_IF:
  3029. X        switch (expr_eval_condition(sp->s_if.sif_cond))
  3030. X        {
  3031. X        case -1:
  3032. X            status = STMT_ERROR;
  3033. X            break;
  3034. X
  3035. X        case 0:
  3036. X            status = stmt_eval(sp->s_if.sif_false);
  3037. X            break;
  3038. X
  3039. X        default:
  3040. X            status = stmt_eval(sp->s_if.sif_true);
  3041. X            break;
  3042. X        }
  3043. X        break;
  3044. X
  3045. X    case OP_LOOP:
  3046. X        do
  3047. X            status = stmt_eval(sp->s_loop);
  3048. X        while
  3049. X            (status == STMT_OK);
  3050. X        if (status == STMT_LSTOP)
  3051. X            status = STMT_OK;
  3052. X        break;
  3053. X
  3054. X    case OP_LOOPSTOP:
  3055. X        status = STMT_LSTOP;
  3056. X        break;
  3057. X
  3058. X    case OP_NOP:
  3059. X        break;
  3060. X
  3061. X    case OP_RECIPE:
  3062. X        {
  3063. X            recipe        r;
  3064. X            int        j;
  3065. X            int        imp;
  3066. X
  3067. X            /*
  3068. X             * A recipe in the grammar has expression lists for
  3069. X             * both targets and prerequisites.  These must be
  3070. X             * evaluated into word lists when the recipes are
  3071. X             * instanciated.
  3072. X             */
  3073. X            if (el2wl(&r.r_target, &sp->s_recipe.sr_target))
  3074. X            {
  3075. X                status = STMT_ERROR;
  3076. X                break;
  3077. X            }
  3078. X            if (r.r_target.wl_nwords == 0)
  3079. X            {
  3080. X                error
  3081. X                (
  3082. X            "%s: %d: attempt to instanciate recipe with no targets",
  3083. X                    sp->s_recipe.sr_position.pos_name
  3084. X                        ->str_text,
  3085. X                    sp->s_recipe.sr_position.pos_line
  3086. X                );
  3087. X                option_set_errors();
  3088. X                status = STMT_ERROR;
  3089. X                break;
  3090. X            }
  3091. X            el_copy(&r.r_need, &sp->s_recipe.sr_need);
  3092. X            el_copy(&r.r_need2, &sp->s_recipe.sr_need2);
  3093. X            r.r_precondition =
  3094. X                (
  3095. X                    sp->s_recipe.sr_precondition
  3096. X                ?
  3097. X                    expr_copy(sp->s_recipe.sr_precondition)
  3098. X                :
  3099. X                    (expr*)0
  3100. X                );
  3101. X            r.r_flags = sp->s_recipe.sr_flags;
  3102. X            r.r_action =
  3103. X                (
  3104. X                    sp->s_recipe.sr_action
  3105. X                ?
  3106. X                    stmt_copy(sp->s_recipe.sr_action)
  3107. X                :
  3108. X                    (stmt*)0
  3109. X                );
  3110. X            r.r_use_action =
  3111. X                (
  3112. X                    sp->s_recipe.sr_use_action
  3113. X                ?
  3114. X                    stmt_copy(sp->s_recipe.sr_use_action)
  3115. X                :
  3116. X                    (stmt*)0
  3117. X                );
  3118. X            r.r_tag = recipe_tag();
  3119. X            r.r_multiple = sp->s_recipe.sr_multiple;
  3120. X
  3121. X            /*
  3122. X             * is it implicit or explicit?
  3123. X             */
  3124. X            imp = 0;
  3125. X            for (j = 0; j < r.r_target.wl_nwords; ++j)
  3126. X            {
  3127. X                if (strchr(r.r_target.wl_word[j]->str_text, MATCH_CHAR))
  3128. X                {
  3129. X                    imp = 1;
  3130. X                    break;
  3131. X                }
  3132. X            }
  3133. X
  3134. X            /*
  3135. X             * add it to the list
  3136. X             */
  3137. X            if (imp)
  3138. X            {
  3139. X                rl_append(&implicit, &r);
  3140. X#if 0
  3141. X                if (!r.r_need.el_nexprs)
  3142. X                {
  3143. X                    error
  3144. X                    (
  3145. X                     "%s: %d: implicit recipe must have action",
  3146. X                        sp->s_recipe.sr_position
  3147. X                            .pos_name->str_text,
  3148. X                        sp->s_recipe.sr_position
  3149. X                            .pos_line
  3150. X                    );
  3151. X                    option_set_errors();
  3152. X                }
  3153. X#endif
  3154. X            }
  3155. X            else
  3156. X                rl_append(&explicit, &r);
  3157. X
  3158. X            /*
  3159. X             * emit trace information, if enabled
  3160. X             */
  3161. X            if (option_test(OPTION_TRACE))
  3162. X            {
  3163. X                error
  3164. X                (
  3165. X                    "%s: %d: %s recipe %d instanciated (trace)",
  3166. X                    sp->s_recipe.sr_position.pos_name
  3167. X                        ->str_text,
  3168. X                    sp->s_recipe.sr_position.pos_line,
  3169. X                    imp ? "implicit" : "explicit",
  3170. X                    r.r_tag
  3171. X                );
  3172. X            }
  3173. X        }
  3174. X        break;
  3175. X
  3176. X    case OP_TOUCH:
  3177. X        {
  3178. X            wlist     wl;
  3179. X
  3180. X            /*
  3181. X             * The grammar has the command as an expression list.
  3182. X             * Evaluate the expression list into a word list.
  3183. X             * This word list is the command to execute.
  3184. X             */
  3185. X            if (el2wl(&wl, &sp->s_cmd.c_args))
  3186. X            {
  3187. X                status = STMT_ERROR;
  3188. X                break;
  3189. X            }
  3190. X            if (!option_test(OPTION_SILENT))
  3191. X            {
  3192. X                string_ty *s;
  3193. X
  3194. X                /*
  3195. X                 * If the command has not been silenced,
  3196. X                 * form it into a string and echo it.
  3197. X                 */
  3198. X                s = wl2str(&wl, 0, 32767);
  3199. X                error("touch %s", s->str_text);
  3200. X                str_free(s);
  3201. X            }
  3202. X            if (option_test(OPTION_ACTION))
  3203. X            {
  3204. X                int        j;
  3205. X
  3206. X                for (j = 0; j < wl.wl_nwords; j++)
  3207. X                    if (os_touch(wl.wl_word[j]))
  3208. X                        status = STMT_ERROR;
  3209. X            }
  3210. X            wl_free(&wl);
  3211. X        }
  3212. X        break;
  3213. X    }
  3214. Xret:
  3215. X    trace(("return %d;\n", status));
  3216. X    trace((/*{*/"}\n"));
  3217. X    return status;
  3218. X}
  3219. X
  3220. X
  3221. X/*
  3222. X *  NAME
  3223. X *    sl_append - append to a statement list
  3224. X *
  3225. X *  SYNOPSIS
  3226. X *    void sl_append(slist *slp, stmt *sp);
  3227. X *
  3228. X *  DESCRIPTION
  3229. X *    Sl_append is used to append a statement to a statement list.
  3230. X */
  3231. X
  3232. Xvoid
  3233. Xsl_append(sl, s)
  3234. X    slist        *sl;
  3235. X    stmt        *s;
  3236. X{
  3237. X    trace(("sl_append(sl = %08X, s = %08X)\n{\n"/*}*/, sl, s));
  3238. X    *(stmt **)
  3239. X    enlarge
  3240. X    (
  3241. X        &sl->sl_nstmts,
  3242. X        (char**)&sl->sl_stmt,
  3243. X        sizeof(stmt *)
  3244. X    ) = stmt_copy(s);
  3245. X    trace((/*{*/"}\n"));
  3246. X}
  3247. X
  3248. X
  3249. X/*
  3250. X *  NAME
  3251. X *      sl_free - free statement list
  3252. X *
  3253. X *  SYNOPSIS
  3254. X *      void sl_free(slist *);
  3255. X *
  3256. X *  DESCRIPTION
  3257. X *      The sl_free function is used to free the list of statement trees.
  3258. X *
  3259. X *  RETURNS
  3260. X *      void
  3261. X */
  3262. X
  3263. Xvoid
  3264. Xsl_free(sl)
  3265. X    slist        *sl;
  3266. X{
  3267. X    int        j;
  3268. X
  3269. X    trace(("sl_free(sl = %08X)\n{\n"/*}*/, sl));
  3270. X    for (j = 0; j < sl->sl_nstmts; ++j)
  3271. X        stmt_free(sl->sl_stmt[j]);
  3272. X    if (sl->sl_nstmts)
  3273. X        mem_free((char *)sl->sl_stmt);
  3274. X    sl->sl_nstmts = 0;
  3275. X    sl->sl_stmt = 0;
  3276. X    trace((/*{*/"}\n"));
  3277. X}
  3278. X
  3279. Xvoid
  3280. Xsl_zero(slp)
  3281. X    slist        *slp;
  3282. X{
  3283. X    slp->sl_nstmts = 0;
  3284. X    slp->sl_stmt = 0;
  3285. X}
  3286. END_OF_FILE
  3287. if test 13734 -ne `wc -c <'cook/stmt.c'`; then
  3288.     echo shar: \"'cook/stmt.c'\" unpacked with wrong size!
  3289. fi
  3290. # end of 'cook/stmt.c'
  3291. fi
  3292. echo shar: End of archive 7 \(of 11\).
  3293. cp /dev/null ark7isdone
  3294. MISSING=""
  3295. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  3296.     if test ! -f ark${I}isdone ; then
  3297.     MISSING="${MISSING} ${I}"
  3298.     fi
  3299. done
  3300. if test "${MISSING}" = "" ; then
  3301.     echo You have unpacked all 11 archives.
  3302.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3303. else
  3304.     echo You still need to unpack the following archives:
  3305.     echo "        " ${MISSING}
  3306. fi
  3307. ##  End of shell archive.
  3308. exit 0
  3309.